Base64 File Upload API: Send Files as JSON and Get a URL
Most file upload APIs expect multipart/form-data. That is the right default for browsers, servers, and large files. But it is not always convenient. Some workflow tools, AI agents, database scripts, and webhook platforms can create a base64 string easily, but make multipart uploads awkward.
For those cases, FilePost supports a JSON upload format: send a filename, content type, and base64-encoded file content, then receive a permanent public CDN URL in the response.
When Base64 Uploads Make Sense
Use a base64 file upload API when the source system naturally gives you a string or JSON object instead of a file stream. Common examples:
- Low-code workflows where the previous step outputs a base64 field.
- AI tools that can generate or transform files and pass structured JSON onward.
- Webhook processors that receive file content inside a JSON payload.
- Database automations that store a generated PDF, CSV, or image as a base64 value.
- Serverless functions where keeping everything as JSON simplifies the integration.
For large uploads, use multipart. Base64 adds overhead and can hit request body limits faster. For small generated files, reports, images, PDFs, CSV exports, and automation handoffs, JSON is often simpler.
Request Format
The endpoint accepts a normal authenticated JSON request:
POST https://filepost.dev/v1/upload/base64
X-API-Key: fh_your_api_key
Content-Type: application/json
The request body contains the file metadata and base64 content:
{
"filename": "report.csv",
"content_type": "text/csv",
"data_base64": "bmFtZSx0b3RhbApGaWxlUG9zdCw0Mg=="
}
The response matches the regular upload API:
{
"file_id": "a1b2c3d4e5f6",
"url": "https://cdn.filepost.dev/file/filepost/uploads/a1/a1b2c3/report.csv",
"name": "report.csv",
"size": 22,
"content_type": "text/csv"
}
cURL Example
Here is the smallest useful test. It uploads a text file from a base64 string and returns a public URL:
curl -X POST https://filepost.dev/v1/upload/base64 \
-H "X-API-Key: fh_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"filename": "hello.txt",
"content_type": "text/plain",
"data_base64": "SGVsbG8gZnJvbSBGaWxlUG9zdAo="
}'
If you already have a local file and want to encode it first:
BASE64=$(base64 -i invoice.pdf)
curl -X POST https://filepost.dev/v1/upload/base64 \
-H "X-API-Key: fh_your_api_key" \
-H "Content-Type: application/json" \
-d "{\"filename\":\"invoice.pdf\",\"content_type\":\"application/pdf\",\"data_base64\":\"$BASE64\"}"
JavaScript Example
In Node.js, read a file, convert it to base64, and upload it as JSON:
import fs from "node:fs/promises";
const file = await fs.readFile("./invoice.pdf");
const res = await fetch("https://filepost.dev/v1/upload/base64", {
method: "POST",
headers: {
"X-API-Key": process.env.FILEPOST_API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
filename: "invoice.pdf",
content_type: "application/pdf",
data_base64: file.toString("base64")
})
});
const uploaded = await res.json();
console.log(uploaded.url);
Python Example
Python is similar. This is useful for scripts that generate a PDF or CSV and need a URL immediately afterward:
import base64
import requests
with open("report.csv", "rb") as f:
data_base64 = base64.b64encode(f.read()).decode("ascii")
response = requests.post(
"https://filepost.dev/v1/upload/base64",
headers={
"X-API-Key": "fh_your_api_key",
"Content-Type": "application/json",
},
json={
"filename": "report.csv",
"content_type": "text/csv",
"data_base64": data_base64,
},
)
response.raise_for_status()
print(response.json()["url"])
Adding Auto-Delete
If the file should not live forever, add expires_in. This is useful for temporary exports, approval links, generated previews, or files that should disappear after a workflow completes.
{
"filename": "preview.pdf",
"content_type": "application/pdf",
"data_base64": "...",
"expires_in": "7d"
}
Use permanent URLs for assets you need to reference long-term. Use expires_in when the URL is only part of a short-lived process.
Base64 vs Multipart Uploads
| Need | Use | Why |
|---|---|---|
| Browser file picker | Multipart | Native FormData support |
| Large files | Multipart | Less overhead than base64 |
| Generated JSON payload | Base64 | No multipart builder needed |
| Low-code tools | Base64 | Many tools pass strings more reliably than files |
| Server-to-server scripts | Either | Choose based on payload size and convenience |
Common Errors
Invalid API Key
All authenticated upload endpoints require X-API-Key. Create one from the signup modal or the API:
curl -X POST https://filepost.dev/v1/signup \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com"}'
Bad Base64
Make sure the value is only the base64 data, not a full data URL. Send SGVsbG8=, not data:text/plain;base64,SGVsbG8=.
File Too Large
Remember that base64 increases the payload size. If a file is close to your plan limit or your client request limit, use multipart instead.
Upload Files from JSON
Use FilePost when your tool can produce base64 but cannot send multipart/form-data cleanly.
Get Your API Key