DW Alliance app

API overview for app.dwalliance.com. Create an account, start a session, then upload an HTML page and its related files.

Modules

/account_setup/ Create a person, email, optional company, and a new brand. No session required.
/session/ Email a one-time session id for an email + brand. Response is ok and mailed only.
/files/ Create, update, delete, and read files. Uploads need a session with FILE rights.

1. Create an account

  1. POST JSON to /account_setup/ with {"email":"you@example.com"}. You get back id. A 6-character confirmation code is emailed from support@dwalliance.com. It expires after 30 minutes.
  2. POST JSON again with id, confirmation_id, first_name, last_name, and optional company_name.
  3. Success returns ok, person_id, company_id, and emailed. A second email delivers your brand code. Keep that code; it is not in the JSON.
// step 1
await fetch('/account_setup/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'you@example.com' })
}).then(r => r.json());

// step 2
await fetch('/account_setup/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    id: 'SETUP_ID',
    confirmation_id: 'xxxxxx',
    first_name: 'Ada',
    last_name: 'Lovelace',
    company_name: 'Example LLC'
  })
}).then(r => r.json());

New brands get default data_access for LOGIN (READ), FILE (CREATE/READ/UPDATE/DELETE), and CRM (CREATE/READ/UPDATE/DELETE).

2. Start a session

  1. POST JSON to /session/ with your email and brand code.
  2. If they match, a session id is emailed. The HTTP body is only {"ok":true,"mailed":true}.
  3. Send that session id later as JSON field session or cookie session.
await fetch('/session/', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'you@example.com', brand: 'BRANDCODE' })
}).then(r => r.json());

3. Upload an HTML document and its files

Use /files/ with action create. Set public_private to PUBLIC for pages browsers should open. Keep related assets under the same brand and a shared file_path.

  1. Upload index.html (or any page) with file_path like site.
  2. Upload CSS, JS, images, fonts the same way. Match the relative paths your HTML uses.
  3. Open the public URL: /BRANDCODE/file_path/file_name. Example: /3b8fc9c3c9/site/index.html.

JSON create (base64)

const html = btoa('<!DOCTYPE html><html><body>Hello</body></html>');
await fetch('/files/', {
  method: 'POST',
  credentials: 'include',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    action: 'create',
    session: 'SESSION_ID_FROM_EMAIL',
    file_name: 'index.html',
    file_path: 'site',
    file_type: 'HTML',
    public_private: 'PUBLIC',
    file_data: html
  })
}).then(r => r.json());

Multipart create

const body = new FormData();
body.append('action', 'create');
body.append('session', 'SESSION_ID_FROM_EMAIL');
body.append('file_name', 'hero.png');
body.append('file_path', 'site');
body.append('public_private', 'PUBLIC');
body.append('file', fileInput.files[0]);
await fetch('/files/', { method: 'POST', credentials: 'include', body }).then(r => r.json());

Also supported: update, delete, and read. PUBLIC files can be read without a session. Max upload size is about 10 MB. GET each module path with no body for its live help JSON.

Public URLs

After a PUBLIC file is created, the first request for /{brand}/{file_path}/{file_name} writes a cache on the app node and serves it. Updates and deletes clear that cache automatically.