dontlosedata: a database in one URL
Save and load your app's data with a single web address. No server to set up, no database to manage, nothing to install. Built for people making apps with AI tools, and for developers who want storage in seconds.
- Get a free endpoint instantly: https://dontlosedata.site
- Endpoint URL:
https://dontlosedata.site/api/v1/<uuid> - This document as plain text (for AI assistants): https://dontlosedata.site/llms.txt
What it is
dontlosedata gives you a private web address, called an endpoint, that works like a small online notebook for your app. Your app can write information to it, read it back, change it and delete it, from any device and any website.
You don't need to rent a server, install a database or learn a backend framework. If your app can load a web page, it can use dontlosedata.
The problem it solves
Building an app has never been easier. Tools like Lovable, Replit, ChatGPT, Claude and v0 can make a working screen in minutes. But as soon as the app needs to remember something (a todo, a high score, a product price), you hit a wall:
- The data disappears. It only lives in the browser, so it's gone on reload, and nobody else can see it.
- "Now set up a backend." The usual answer is a database service with accounts, tables, permissions, keys and settings. That takes hours, and it's the part AI tools most often get wrong.
- Errors you can't fix. Messages about CORS, missing keys or failed connections stop non-developers cold.
dontlosedata removes that wall. You get one URL, your AI gets one short set of instructions, and saving data just works.
What you can build
- Todo lists, notes and habit trackers that stay in sync between your phone and laptop.
- Game leaderboards and saved progress.
- Product lists, menus and price lists you edit from the dashboard instead of rebuilding the site.
- Expense, workout and reading logs that follow you from phone to laptop.
- Site content you can change without republishing: announcements, opening hours, FAQs, portfolio projects, on/off switches for features.
- Event schedules and timetables that you update in one place.
- Internal tools for a team: stock counts, checklists, equipment lists.
- Prototypes, demos and hackathon projects that need real data today, not after a week of setup.
- Classroom projects where students should focus on the app, not on servers.
Ideas by audience: Restaurants & cafés · Small shops & makers · Personal tools · Creators & freelancers · Teachers & tutors · Events & communities · Gyms, studios & coaches · Game makers
Where it works
Anywhere that can send a web request:
- AI app builders: Lovable, Replit, v0, Bolt
- AI assistants and editors: ChatGPT, Claude, Cursor
- Websites: plain HTML pages, and site builders that let you add a custom form or code
- Automation tools that can call a URL, such as Zapier, Make or n8n
- Mobile apps, scripts and servers in any programming language
Features
- Ready in one click. Open the homepage and your endpoint already exists. No account needed to try it.
- Made for AI builders. Copy one ready-made prompt that contains your endpoint and the rules. Paste it into your AI tool and describe what you want.
- Read, add, change and delete any part of your data. Find items by any field, filter, sort and page through long lists.
- Forms without code. Point any HTML form at your endpoint and every submission is saved. A built-in trap catches spam bots.
- Works from any website. No CORS errors. If you want, allow only your own websites.
- Lock it down when you need to. Add API keys so that only your app can change the data, or so that nobody can read it without a key.
- A dashboard for your data. Browse and edit what's stored, see every request as it happens, and track daily and monthly usage.
- Clear error messages. Every error says what went wrong and how to fix it, so your AI assistant can correct itself.
- Sign in with Google to keep your endpoints, create more and manage them in one place.
Getting started
- Open https://dontlosedata.site. Your endpoint is created right away.
- Click Copy my prompt and paste it into Lovable, Replit, ChatGPT, Claude, v0, Bolt or Cursor.
- Tell your AI what to build. Everything your app saves goes to your endpoint.
- Want to keep it? Sign in with Google and the endpoint moves into your account.
Prefer to write code yourself? Skip to the technical reference.
Good to know
- Is my data private? Your endpoint address contains a long random ID that can't be guessed, but anyone who has the address can use it. Don't store personal details (names, email addresses, phone numbers), passwords, payment details, health records or other sensitive information. Add an API key to protect an endpoint.
- I changed a setting. Does my AI need to know? Yes. When you add an API key or limit which websites can use an endpoint, the dashboard gives you an updated prompt. Paste it into your AI and it updates your app.
- What does it cost? It's free during beta, with no credit card. Paid plans with higher limits are coming.
- Do I need an account? No. Endpoints made without an account work right away, but they are deleted if unused for 3 hours, or after 30 days without use. Sign in to keep them.
- Can I use it for a real product? For small apps, prototypes, catalogs and internal tools, yes. It's a simple data store, not a replacement for a full database, so keep your own copy of anything important.
Technical reference
Each endpoint stores one JSON value (an object or an array). Read and change it with plain HTTP from any website, app or AI tool. No SDK, no backend, CORS enabled.
1. The idea
The uuid is your endpoint. Everything after it in the URL is a path into your JSON:
https://dontlosedata.site/api/v1/<uuid> the whole JSON
https://dontlosedata.site/api/v1/<uuid>/openingHours the "openingHours" key of an object
https://dontlosedata.site/api/v1/<uuid>/id/101 the item with id 101 in a list
A new endpoint is empty: GET returns null until you write something.
Send JSON with Content-Type: application/json. Responses are always JSON (the raw value, no wrapper). In the examples below, xyz means https://dontlosedata.site/api/v1/<uuid>.
2. Path rules
| The data at this point is… | Path part | Means |
|---|---|---|
| an object | /openingHours |
the value of key openingHours |
| an object | /opening* |
every key matching the * wildcard (returns an object) |
| a list | /id/101 |
the first item whose field id equals 101 |
| a list | /title/B* |
all items whose title matches B* (returns a list) |
| a list | /0, /1, … |
the item at that position (digits only) |
| a list | /*/title |
title from every item (returns a list) |
- Rule of thumb: an exact path returns one thing; any
*returns a list. - Values are compared as text:
/id/101matches101and"101";/done/truematchestrue. - Nested fields use dots:
/details.color/red. - Wildcards ignore upper/lower case:
/title/wat*matchesWater plants. - Paths can continue after a match:
xyz/id/101/titlereturns"Buy milk".
3. Example: an object
Stored JSON:
{
"announcement": "Summer sale this week!",
"openingHours": ["Mon-Fri 9-17", "Sat 10-14"],
"theme": "dark"
}
| Request | Body | Result |
|---|---|---|
GET xyz |
the whole object | |
GET xyz/openingHours |
["Mon-Fri 9-17","Sat 10-14"] |
|
GET xyz/openingHours/1 |
"Sat 10-14" |
|
GET xyz/announcement |
"Summer sale this week!" |
|
PUT xyz/announcement |
"Free shipping today" |
the banner text changes |
PUT xyz/settings/fontSize |
16 |
creates {"settings":{"fontSize":16}} |
POST xyz/openingHours |
"Sun closed" |
appends: ["Mon-Fri 9-17","Sat 10-14","Sun closed"] |
PATCH xyz |
{"theme":"light","announcement":null} |
merges: theme changes, announcement is removed |
DELETE xyz/openingHours/0 |
removes "Mon-Fri 9-17" |
|
DELETE xyz/theme |
removes the key | |
DELETE xyz |
clears the whole endpoint |
4. Example: a list
Stored JSON:
[
{ "id": 101, "title": "Buy milk", "done": false, "dueDate": "2026-01-01" },
{ "id": 102, "title": "Water plants", "done": true, "dueDate": "2026-01-02" }
]
| Request | Body | Result |
|---|---|---|
GET xyz |
the whole list | |
GET xyz/id/101 |
{"id":101,"title":"Buy milk","done":false,"dueDate":"2026-01-01"} |
|
GET xyz/id/101/title |
"Buy milk" |
|
GET xyz/0 |
the first item | |
GET xyz/title/W* |
[{"id":102,…}] |
|
GET xyz/*/title |
["Buy milk","Water plants"] |
|
POST xyz |
{"title":"Read a book"} |
appends {"id":"k3j9x2m1ab7q","title":"Read a book"} (an id is added) |
PUT xyz/id/101 |
{"id":101,"title":"Buy oat milk","done":false} |
replaces item 101 |
PUT xyz/id/105 |
{"title":"Bake bread"} |
item 105 doesn't exist, so it is created with "id":105 |
PATCH xyz/id/101 |
{"done":true} |
merges into item 101 |
PATCH xyz/title/* |
{"done":false} |
merges into every item |
DELETE xyz/id/101 |
removes item 101, returns {"deleted":1} |
|
DELETE xyz/done/true |
removes the first finished item, returns {"deleted":1} |
|
DELETE xyz/title/W* |
removes every match, returns {"deleted":n} |
5. Methods
- GET: read the value at the path.
404if nothing is there. - POST: append the body to the list at the path. If the path is empty or missing, a new list is created, so the very first
POST xyzturns an empty endpoint into[item]. Objects without anidget a uniqueid(turn this off with?_auto_id=false). Returns the saved item with201. POST on an object returns409; use PUT or PATCH there. - PUT: replace the value at the path. Missing keys are created.
PUT xyz/<field>/<value>creates the item if no item matches (upsert).PUT xyzreplaces everything. - PATCH: merge a JSON object into the object(s) at the path (JSON Merge Patch): keys are added or replaced, nested objects are merged, and
nullremoves a key. - DELETE: remove the value at the path, or every match of a wildcard.
DELETE xyzclears the endpoint. Returns{"deleted": n}.
6. Filtering, sorting and paging lists
Add query parameters to any GET that returns a list:
| Query | Meaning |
|---|---|
?done=true |
field equals value |
?category=home&category=work |
either value |
?title=Bu* |
wildcard, ignores case |
?details.color=red |
nested field |
?price_gt=10 _gte _lt _lte |
number or text comparison |
?status_ne=archived |
not equal |
?_sort=-dueDate,title |
sort; - means newest/biggest first |
?_limit=20&_offset=40 |
paging |
?_page=3&_limit=20 |
paging by page number |
The number of matches before paging is in the X-Total-Count response header.
7. JavaScript
const url = "https://dontlosedata.site/api/v1/<uuid>";
// add
const saved = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Buy milk", done: false }),
}).then((r) => r.json());
// list
const todos = await fetch(url).then((r) => r.json()); // null if empty
// update
await fetch(`${url}/id/${saved.id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ done: true }),
});
// delete
await fetch(`${url}/id/${saved.id}`, { method: "DELETE" });
8. HTML forms
Any HTML form can post to https://dontlosedata.site/f/<uuid>. Each submission is appended as an item (with an id). Add a path to collect submissions under a key, e.g. /f/<uuid>/products. A small "add a product" form is all a shop owner needs to update their catalog without touching code:
<form method="POST" action="https://dontlosedata.site/f/<uuid>/products">
<input name="name" placeholder="Blue mug" required>
<input name="price" type="number" step="0.01" placeholder="12.50" required>
<select name="category">
<option>Kitchen</option>
<option>Garden</option>
</select>
<!-- optional: where to go after submitting (must be the same site as the form) -->
<input type="hidden" name="_redirect" value="https://your-site.com/admin">
<!-- optional spam trap: keep it hidden; bots fill it in -->
<input type="text" name="_gotcha" style="display:none" tabindex="-1" autocomplete="off">
<button>Add product</button>
</form>
Each submission is saved like {"id":"…","name":"Blue mug","price":"12.50","category":"Kitchen"}. Form values always arrive as text, so price is "12.50"; send JSON with fetch if you need real numbers. Without _redirect the visitor sees a simple "Thanks" page. Requests with Accept: application/json get the saved item as JSON. File uploads are not supported. Avoid collecting personal details such as names or email addresses: endpoints are not meant for personal data.
9. API keys (optional)
Endpoints are public by default: anyone with the URL can use them. After signing in you can create API keys and assign them to endpoints. Then choose what needs a key:
- Everything needs a key
- Reading is public, changing needs a key
- Form submissions are public, everything else needs a key
Send the key as Authorization: Bearer <key> or X-API-Key: <key>. Keys placed in browser code are visible to visitors, so prefer "reading is public" or "forms are public" for websites, and keep full keys on servers.
10. CORS and allowed websites
CORS is open: every website can call the API directly from the browser, including with credentials: "include", and with any custom headers. Error responses carry CORS headers too, so you always see the real error message.
Optionally, in the dashboard, add allowed websites (for example https://myapp.com, *.lovable.app, localhost:*). Calls from other websites then get 403 origin_not_allowed. This stops other sites from using your endpoint in a browser; it is not a replacement for an API key.
11. Errors
Errors always look like this:
{ "error": { "code": "path_not_found", "message": "Nothing found at '/id/999'.", "hint": "…", "docs": "https://dontlosedata.site/llms.txt" } }
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_json, missing_body, incomplete_path, wildcard_not_allowed |
the request is malformed |
| 401 | api_key_required, invalid_api_key |
protected endpoint |
| 403 | origin_not_allowed, blocked, endpoint_blocked, endpoint_limit |
not allowed |
| 404 | endpoint_not_found, path_not_found |
nothing there |
| 409 | not_a_list, not_an_object, cannot_go_deeper |
the method doesn't fit the data type |
| 413 | payload_too_large, endpoint_full, storage_full |
size limits |
| 422 | body_must_be_object, files_not_supported |
wrong body |
| 429 | rate_limited, quota_exceeded |
slow down; see Retry-After |
12. Limits
Every response includes X-RateLimit-Limit and X-RateLimit-Remaining. Endpoints created without an account allow 30 requests per minute, 1,000 per day, 32 KB per request and 256 KB of data. They are deleted if unused for 180 minutes, or after 30 days without requests. Sign in for higher limits and to keep endpoints.