Upload from the browser without exposing your key
Your server trades its API key for a short, limited upload token. The browser uploads straight to BasiX with that token. The key never reaches the page.
1.Keep the key on your server
Create an upload-only key in Dashboard → API keys and store it as an environment variable on your server, never in front-end code.
bashBASIX_API_KEY=bx_live_…2.Add a route that mints an upload token
POST https://upload.basix.media/api/upload-token with your key. Optional JSON fields: folder (where files land), maxSizeMb (per-file ceiling) and expiresIn (seconds, 60 to 31536000, default 3600). Check who is asking before answering: this route hands out the right to write to your storage.
javascriptapp.post('/upload-token', requireSignedIn, async (req, res) => { const response = await fetch('https://upload.basix.media/api/upload-token', { method: 'POST', headers: { Authorization: `Bearer ${process.env.BASIX_API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ folder: 'user-uploads', maxSizeMb: 10, expiresIn: 600 }), }) res.status(response.status).json(await response.json()) })3.Upload from the browser
The browser fetches a token from your route, then sends the file as multipart form data, field "file", with the token as a Bearer. Cross-origin requests are allowed for these tokens.
javascriptasync function uploadToBasix(file) { const tokenResponse = await fetch('/upload-token', { method: 'POST' }) if (!tokenResponse.ok) throw new Error('Could not get an upload token') const { token } = await tokenResponse.json() const form = new FormData() form.append('file', file) const response = await fetch('https://upload.basix.media/api/v1/upload', { method: 'POST', headers: { Authorization: `Bearer ${token}` }, body: form, }) const body = await response.json() if (!response.ok) throw new Error(body.error.message) return body.url } document.querySelector('input[type=file]').addEventListener('change', async (event) => { const url = await uploadToBasix(event.target.files[0]) document.querySelector('img').src = url })4.Read the response
A successful upload answers 201 with the public address of the file.
json{ "id": "k3j9x2m1p0qa", "path": "user-uploads/k3j9x2m1p0qa.png", "url": "https://cdn.basix.media/a7k2m9x4/user-uploads/k3j9x2m1p0qa.png", "size": 482113, "mime": "image/png", "name": "photo.png", "replaced": false }
Worth knowing
- A token can only upload. It cannot list, read or delete anything.
- Files are stored as <folder>/<id>.<ext>. A token never overwrites an existing file, and any "path" field sent by the browser is ignored.
- Files larger than maxSizeMb are refused with 413 FILE_TOO_LARGE.
- Tokens are tied to the key that minted them: revoke the key and every token it issued stops working at once. The key’s rate limits apply to its tokens.
- Need a URL that works exactly once instead? Use a presigned upload URL, described in the API reference.