JavaScript
The browser/Node client: a small copy-in module over the REST API.
A client you can read
The Flares Cloud API is plain HTTPS with a bearer key, so the JavaScript client is a small module rather than a dependency. Copy it into your project and own it — every method below maps to one documented endpoint.
// flares.js
export function createClient({ projectId, publicKey, baseUrl = 'https://cloud.flaresinc.com' }) {
const api = `${baseUrl}/v1/projects/${projectId}`;
let accessToken = null;
async function call(path, { method = 'GET', body, userToken = accessToken } = {}) {
const headers = { 'Authorization': `Bearer ${publicKey}` };
if (body) { headers['Content-Type'] = 'application/json'; }
if (userToken) { headers['X-Basket-User-Token'] = userToken; headers['X-Flares-User-Token'] = userToken; }
const res = await fetch(api + path, { method, headers, body: body && JSON.stringify(body) });
const data = await res.json().catch(() => ({}));
if (!res.ok) { throw Object.assign(new Error(data.message || res.statusText), { code: data.error, status: res.status }); }
return data;
}
return {
auth: {
async signUp({ email, password, displayName }) {
const s = await call('/auth/signup', { method: 'POST', body: { email, password, display_name: displayName } });
accessToken = s.access_token;
return s;
},
async signIn({ email, password }) {
const s = await call('/auth/signin', { method: 'POST', body: { email, password } });
accessToken = s.access_token;
return s;
},
async requestCode(email) { return call('/auth/otp/request', { method: 'POST', body: { email } }); },
async signInWithCode(email, code) {
const s = await call('/auth/otp/redeem', { method: 'POST', body: { email, code } });
accessToken = s.access_token;
return s;
},
async user() { return (await call('/auth/user')).user; },
async refresh(refreshToken) {
const s = await call('/auth/refresh', { method: 'POST', body: { refresh_token: refreshToken } });
accessToken = s.access_token;
return s;
},
async signOut(refreshToken) { accessToken = null; return call('/auth/signout', { method: 'POST', body: { refresh_token: refreshToken } }); },
async signOutEverywhere() { return call('/auth/signout-all', { method: 'POST' }); },
async sendPasswordReset(email) { return call('/auth/password/forgot', { method: 'POST', body: { email } }); },
setToken(token) { accessToken = token; },
},
collection(name) {
return {
async list(query = {}) {
const params = new URLSearchParams();
if (query.where) { params.set('where', JSON.stringify(query.where)); }
if (query.orderBy) { params.set('orderBy', query.orderBy); }
if (query.direction) { params.set('direction', query.direction); }
if (query.limit) { params.set('limit', String(query.limit)); }
if (query.cursor) { params.set('cursor', query.cursor); }
return call(`/collections/${name}/records?${params}`);
},
async get(id) { return (await call(`/collections/${name}/records/${id}`)).record; },
async create(data) { return (await call(`/collections/${name}/records`, { method: 'POST', body: { data } })).record; },
async update(id, data, version) {
return (await call(`/collections/${name}/records/${id}`, { method: 'PATCH', body: { data, version } })).record;
},
async remove(id) { return call(`/collections/${name}/records/${id}`, { method: 'DELETE' }); },
};
},
async invoke(functionName, { method = 'POST', body } = {}) {
const headers = {};
if (accessToken) { headers['X-Flares-User-Token'] = accessToken; }
if (body) { headers['Content-Type'] = 'application/json'; }
const res = await fetch(`${baseUrl}/run/${projectId}/${functionName}`,
{ method, headers, body: body && JSON.stringify(body) });
return { status: res.status, requestId: res.headers.get('X-Flares-Request-Id'), data: await res.json().catch(() => null) };
},
};
}
Using it
import { createClient } from './flares.js';
const flares = createClient({ projectId: 'prj_…', publicKey: 'basket_public_…' });
await flares.auth.signUp({ email, password });
const messages = await flares.collection('messages').list({
where: [['room_id', '==', roomId]], orderBy: 'created_at', direction: 'desc', limit: 50
});
await flares.collection('messages').create({ body: 'Hello', sender_id: (await flares.auth.user()).id });
const { data } = await flares.invoke('create-shipment', { body: { destination: 'Kano' } });
Use the public key here. A secret key in frontend code is an administrator
credential in every visitor's browser. About keys →
Realtime
Live subscriptions use a WebSocket rather than fetch — see Realtime and the protocol reference.