Lesson 4 / 98 min read
Platform APIs: files, email, webhooks, AI
devany.files, devany.mail, devany.hook and devany.ai — gates, quotas and error codes.
The SDK surface
Always on
devany.db — shared datadevany.files — image storagedevany.auth / devany.user
Owner-enabled
devany.mail — transactional emaildevany.hook — webhook bridgedevany.ai — in-app intelligence
Behaviour when off
The call doesn't crash, it throws a code'mail_disabled' · 'hook_disabled' · 'ai_disabled'Your UI must degrade with a polite message
Image upload (devany.files)
js
// Dosya seçici <input type="file" accept="image/*"> — mobilde kamerayı da açar.
const file = input.files[0];
const { url } = await devany.files.upload(file); // SDK istemcide küçültür
// Kayıtta yalnız URL saklanır — asla base64 gömme (doküman 20K karakter).
await devany.db.put('boats', { name, price, photo: url });
await devany.files.remove(url); // kayıt silinince görseli de sil
const { used, quota } = await devany.files.usage();Uploads can fail: translate 'file_too_large' and 'quota_exceeded' into a human message and always keep an image-less fallback.
Transactional email and webhooks
js
// Tek alıcılı işlemsel e-posta — rezervasyon onayı, sipariş bildirimi.
try {
await devany.mail.send({
to: booking.email,
subject: 'Randevunuz onaylandı',
text: `${booking.name}, randevunuz ${booking.at} için alındı.`,
});
} catch (e) {
if (e.message === 'mail_disabled') showNote('E-posta kapalı');
else if (e.message === 'test_mode_owner_only') showNote('Taslakta yalnız sahibe gider');
}
// Alan olayını sahibin otomasyonuna (Zapier/Make/n8n) ilet.
await devany.hook.send('booking.created', { id: booking.id, at: booking.at });On a draft app email is in TEST mode: it only reaches the owner's address, prefixed with [TEST]. Quotas and charging live on the server.
In-app intelligence (devany.ai)
js
// Metin — kısa, yapılandırılmış çıktı iste; sohbet dökümü değil.
const summary = await devany.ai.ask(
'Bu ayın randevularını 3 maddede özetle: ' + JSON.stringify(rows).slice(0, 4000),
{ system: 'Kısa, sayısal ve iddiasız yaz.' }
);
// Görsel yorumlama ve üretme
const alt = await devany.ai.see(photoUrl, 'Bu üründe ne var?');
const hero = await devany.ai.image('Minimal, sıcak beyaz arka planlı ürün fotoğrafı');When it's off the call throws 'ai_disabled' — hide or gracefully disable the feature rather than showing a broken screen.
Gate, quota and cost
| Owner must enable | Consumes credit | Works on a draft | |
|---|---|---|---|
| devany.db / devany.user | |||
| devany.files | |||
| devany.mail | Owner only | ||
| devany.hook | |||
| devany.ai |
Key takeaways
- Data and files are always on; email, webhooks and AI depend on the owner's switch.
- A disabled capability doesn't crash — it throws a code for you to catch.
- Images go to file storage, not the record; the record keeps only the URL.
Related topics
Runtime and APIs
Data API: devany.db and devany.user
Shared collections vs the per-user store — same shape, different scope.
Security and advanced topics
The security model
How apps are isolated from each other and from the platform.
Security and advanced topics
Best practices and advanced configuration
The patterns that keep an app solid: mobile, state, failure tolerance and cost.
Still stuck? Ask the assistant in the corner, or browse the FAQ.