Developer docs
Everything a tool can do inside the marketplace. The builder already knows all of this, so you only need this page when you write the code yourself.
1. Anatomy of a tool
A tool consists of three parts that you edit in the builder: HTML (body markup), CSS and JavaScript. The platform wraps them into a full document and runs it inside a sandboxed iframe. You can also paste a complete <html> document into the HTML field.
Browser storage does not work inside a tool. The sandbox gives every tool an opaque origin, where localStorage, sessionStorage, document.cookie and indexedDB all throw a SecurityError. Anything that has to survive a reload belongs in aitools.db or aitools.udb, which means the tool needs the database or the user-accounts type. (An administrator can lift this by serving tools from a separate host, see Admin → Settings.)
Uploaded assets (images, JSON, fonts) are reachable via aitools.fileUrl('name.png').
2. Tool types
- Static – plain HTML/CSS/JS, no server. State lives in JavaScript variables and is gone after a reload.
- With database – a shared key/value store on the server (
aitools.db). - With user accounts – the tool gets its own registration/login plus a per-user store (
aitools.user,aitools.udb). Plus plan and above.
3. Runtime SDK (window.aitools)
aitools.tool // {id, slug, title, type}
aitools.fileUrl(name) // URL of an uploaded asset
// Shared database (types: data, users) – all values are JSON
await aitools.db.get('settings') // -> value or null
await aitools.db.set('todo:1', {text:'Buy milk', done:false})
await aitools.db.remove('todo:1')
await aitools.db.list('todo:') // -> [{key, value, updated_at}] (max 500)
await aitools.db.increment('visits', 1) // -> new number
// User accounts (type: users)
await aitools.user.register('alice', 'secret123', {theme:'dark'})
await aitools.user.login('alice', 'secret123') // -> {id, username, profile}
await aitools.user.me() // -> user or null (session persists per tab)
await aitools.user.updateProfile({theme:'light'})
await aitools.user.logout()
// Per-user database – same API as aitools.db, private to the logged-in user
await aitools.udb.set('notes', [...])
All calls return Promises and reject with an Error whose message explains the problem (limit reached, not logged in, …). Values are limited to 64 KB, keys to 190 characters. Row limits depend on the creator's plan.
4. Example: guestbook with database
// HTML
<form id="f"><input id="name" placeholder="Your name"><input id="msg" placeholder="Message"><button>Post</button></form>
<ul id="list"></ul>
// JS
async function load() {
const rows = await aitools.db.list('entry:');
list.innerHTML = rows.reverse().map(r => `<li><b>${r.value.name}</b>: ${r.value.msg}</li>`).join('');
}
f.addEventListener('submit', async e => {
e.preventDefault();
await aitools.db.set('entry:' + Date.now(), {name: name.value, msg: msg.value});
f.reset(); load();
});
load();
5. Your tool's address
When this marketplace runs tools on their own subdomain, your tool answers at
your-slug.tools.example.com and every copy of it at its-slug.tools.example.com –
the address is shown on the tool page and in the builder. A copy's address is a complete tool for the
people you hand it to: no account here, no marketplace around it.
Renaming a tool changes its slug, and with it the address. Old links stop working, so share the new one after a rename.
Tool data still belongs in aitools.db and aitools.udb, never in
localStorage: only the database travels with exports, downloads and copies, and only it
survives a visitor clearing their browser.
6. Downloads & portability
Creators can download the full source (ZIP) and a JSON export of the database and user list at any time. Buyers can download the source if the creator allows it. Static tools run anywhere; database tools need a backend that implements the SDK contract above if you host them elsewhere.