Skip to content
Mailraft
Sign InGet Started
Browse documentation
Developers

Code examples

Before you run an example

These are HTTP client examples for the implemented MailRaft API, not language SDKs. Configure MAILRAFT_API_URL with your approved local or staging API origin and MAILRAFT_API_KEY with a scoped server-side key. Never place keys in browser code. Requests have timeouts and do not automatically follow redirects or retry.

The scope shown for each operation is required. Use resources belonging to the key’s company. Read responses can contain private content; do not paste them into logs or support messages. Source paths below are relative to the MailRaft repository.

Dashboard

Project source: apps/web/src/review/FernlyOverview.tsx

List inbox messages

POST /v1/call · Scope: messages:read

Returns up to 50 non-deleted messages for the company bound to the key.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List inbox messages. Required key scope: messages:read.
// Retrieve up to 50 messages belonging to the workspace bound to this key.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"messages.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170007_scoped_keys.sql

Read an operation

POST /v1/call · Scope: operations:read

Replace the example UUID with an operation belonging to your company. Provider acceptance and delivery are separate states.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Read an operation. Required key scope: operations:read.
// Replace the id with an operation belonging to your workspace.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"operations.read","payload":{"id":"00000000-0000-4000-8000-000000000001"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170007_scoped_keys.sql

Inbox & drafts

Project source: apps/web/src/review/ReviewApp.tsx
apps/web/src/review/WorkspacePages.tsx

List inbox messages

POST /v1/call · Scope: messages:read

Returns up to 50 non-deleted messages for the company bound to the key.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List inbox messages. Required key scope: messages:read.
// Retrieve up to 50 messages belonging to the workspace bound to this key.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"messages.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170007_scoped_keys.sql

Approvals

Project source: apps/web/src/review/WorkspacePages.tsx

Human approval is required. The dashboard review flow is a local preview; there is no public approvals-list endpoint.

No public API example is available for this page yet. Consult the source files for the current UI implementation.

Domains

Project source: apps/web/src/review/DomainList.tsx
apps/web/src/review/AddDomain.tsx

Persisted tenant domains with DNS TXT ownership verification. SES sender activation is separate. Requires migration 038 and the configured API/database service.

Create domain

POST /v1/call · Scope: domains:manage

Owner-only writes. Replace the domain or ID with your own. Verification checks the returned TXT record; it does not activate email sending.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Create domain. Required key scope: domains:manage.
// Replace the name with a domain you own; save the returned id and TXT record.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"domains.create","payload":{"name":"updates.example.com"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/domain-service.ts

List domains

POST /v1/call · Scope: domains:read

Owner-only writes. Replace the domain or ID with your own. Verification checks the returned TXT record; it does not activate email sending.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List domains. Required key scope: domains:read.
// Retrieve the domains belonging to the workspace bound to this key.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"domains.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/domain-service.ts

Retrieve domain

POST /v1/call · Scope: domains:read

Owner-only writes. Replace the domain or ID with your own. Verification checks the returned TXT record; it does not activate email sending.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Retrieve domain. Required key scope: domains:read.
// Replace the id with a saved domain id from your workspace.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"domains.get","payload":{"id":"00000000-0000-4000-8000-000000000001"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/domain-service.ts

Verify domain

POST /v1/call · Scope: domains:manage

Owner-only writes. Replace the domain or ID with your own. Verification checks the returned TXT record; it does not activate email sending.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Verify domain. Required key scope: domains:manage.
// Add the returned TXT record at your DNS provider before checking ownership.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"domains.verify","payload":{"id":"00000000-0000-4000-8000-000000000001"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Read ownership_status; verified ownership does not activate email sending.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/domain-service.ts

Update domain

POST /v1/call · Scope: domains:manage

Owner-only writes. Replace the domain or ID with your own. Verification checks the returned TXT record; it does not activate email sending.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Update domain. Required key scope: domains:manage.
// Replace the id and send only the settings you want to change.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"domains.update","payload":{"id":"00000000-0000-4000-8000-000000000001","sender_name":"Your business"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/domain-service.ts

Delete domain

POST /v1/call · Scope: domains:manage

Owner-only writes. Replace the domain or ID with your own. Verification checks the returned TXT record; it does not activate email sending.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Delete domain. Required key scope: domains:manage.
// Replace the id with the domain you intend to remove.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"domains.delete","payload":{"id":"00000000-0000-4000-8000-000000000001"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/domain-service.ts

Team & tasks

Project source: apps/web/src/review/TeamTasks.tsx

Team and task controls are local review state. A public task-assignment API is not implemented.

No public API example is available for this page yet. Consult the source files for the current UI implementation.

Contacts

Project source: apps/web/src/review/ContactsPage.tsx

Create contact

POST /v1/call · Scope: contacts:manage

Owner-only. Defaults to no marketing consent; opt_in requires evidence.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Create contact. Required key scope: contacts:manage.
// Replace the contact details. New contacts default to no marketing consent.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"contacts.create","payload":{"email":"person@example.com","name":"Your contact"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/contact-service.ts

List contacts

POST /v1/call · Scope: contacts:read

Returns data, counts and next_cursor. Pass next_cursor as payload.cursor to fetch the next 100 contacts. A record is not marketing consent.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List contacts. Required key scope: contacts:read.
// For the next page, pass the returned next_cursor as payload.cursor.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"contacts.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202610150039_contact_management.sql

Import contacts

POST /v1/call · Scope: contacts:manage

Atomic batch of up to 100 contacts. Duplicates preserve existing consent.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Import contacts. Required key scope: contacts:manage.
// Import up to 100 contacts; duplicates keep their existing consent.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"contacts.import","payload":{"contacts":[{"email":"person@example.com"}]}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/contact-service.ts

Update contact

POST /v1/call · Scope: contacts:manage

Withdrawal also records suppression and suppresses pending campaign recipients. Opt-in cannot remove suppression.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Update contact. Required key scope: contacts:manage.
// Replace the id. Withdrawing consent also adds the contact to suppression.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"contacts.update","payload":{"id":"00000000-0000-4000-8000-000000000001","permission":"withdrawn"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/contact-service.ts

Campaigns

Project source: apps/web/src/review/WorkspacePages.tsx

The example reads potential contacts only. Campaign sends still require consent, suppression checks and human approval.

List contacts

POST /v1/call · Scope: contacts:read

Returns data, counts and next_cursor. Pass next_cursor as payload.cursor to fetch the next 100 contacts. A record is not marketing consent.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List contacts. Required key scope: contacts:read.
// For the next page, pass the returned next_cursor as payload.cursor.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"contacts.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202610150039_contact_management.sql

Connectors

Project source: apps/web/src/review/WorkspacePages.tsx

List connectors

GET /v1/integrations · Scope: integrations:read

The existing API uses integrations in its URL. Dashboard terminology is Connectors.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List connectors. Required key scope: integrations:read.
// Retrieve the saved connectors for the workspace bound to this key.
const response = await fetch(base.replace(/\/$/, '') + '/v1/integrations', {
  method: 'GET',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/server.ts

Webhooks

Project source: apps/web/src/review/DeveloperPages.tsx
apps/public-edge/server.mjs

Provider callback verification exists. A public API for creating, updating or deleting customer webhook subscriptions is not implemented. See the Webhooks guide for verified callback boundaries.

No public API example is available for this page yet. Consult the source files for the current UI implementation.

API and MCP

Project source: apps/web/src/review/DeveloperPages.tsx
apps/api/src/server.ts

List inbox messages

POST /v1/call · Scope: messages:read

Returns up to 50 non-deleted messages for the company bound to the key.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List inbox messages. Required key scope: messages:read.
// Retrieve up to 50 messages belonging to the workspace bound to this key.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"messages.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170007_scoped_keys.sql

List connectors

GET /v1/integrations · Scope: integrations:read

The existing API uses integrations in its URL. Dashboard terminology is Connectors.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List connectors. Required key scope: integrations:read.
// Retrieve the saved connectors for the workspace bound to this key.
const response = await fetch(base.replace(/\/$/, '') + '/v1/integrations', {
  method: 'GET',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: apps/api/src/server.ts

List contacts

POST /v1/call · Scope: contacts:read

Returns data, counts and next_cursor. Pass next_cursor as payload.cursor to fetch the next 100 contacts. A record is not marketing consent.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// List contacts. Required key scope: contacts:read.
// For the next page, pass the returned next_cursor as payload.cursor.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"contacts.list","payload":{}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202610150039_contact_management.sql

Search knowledge

POST /v1/call · Scope: knowledge:read

Returns up to five matching ready knowledge chunks within the authorized company.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Search knowledge. Required key scope: knowledge:read.
// Replace the query with the information you want to find in workspace knowledge.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"knowledge.search","payload":{"query":"opening hours"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170006_workflows.sql

Read an operation

POST /v1/call · Scope: operations:read

Replace the example UUID with an operation belonging to your company. Provider acceptance and delivery are separate states.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Read an operation. Required key scope: operations:read.
// Replace the id with an operation belonging to your workspace.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"operations.read","payload":{"id":"00000000-0000-4000-8000-000000000001"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170007_scoped_keys.sql

Plan & billing

Project source: apps/web/src/review/BillingPage.tsx

Billing is arranged manually. Plan requests open an email draft; there is no checkout API and no automatic payment or plan activation.

No public API example is available for this page yet. Consult the source files for the current UI implementation.

Knowledge

Project source: apps/web/src/review/WorkspacePages.tsx

Search knowledge

POST /v1/call · Scope: knowledge:read

Returns up to five matching ready knowledge chunks within the authorized company.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Search knowledge. Required key scope: knowledge:read.
// Replace the query with the information you want to find in workspace knowledge.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"knowledge.search","payload":{"query":"opening hours"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170006_workflows.sql

Assistant

Project source: apps/web/src/review/WorkspacePages.tsx

Knowledge search supports grounding. This example does not run an AI model or send a message.

Search knowledge

POST /v1/call · Scope: knowledge:read

Returns up to five matching ready knowledge chunks within the authorized company.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Search knowledge. Required key scope: knowledge:read.
// Replace the query with the information you want to find in workspace knowledge.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"knowledge.search","payload":{"query":"opening hours"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170006_workflows.sql

Activity

Project source: apps/web/src/review/WorkspacePages.tsx

Read an operation

POST /v1/call · Scope: operations:read

Replace the example UUID with an operation belonging to your company. Provider acceptance and delivery are separate states.

Node.js 22+. Save as example.mjs and run node example.mjs.

// Load your API origin and scoped key from server environment variables.
const base = process.env.MAILRAFT_API_URL;
const key = process.env.MAILRAFT_API_KEY;
if (!base || !key) throw new Error('Set MAILRAFT_API_URL and MAILRAFT_API_KEY');

// Read an operation. Required key scope: operations:read.
// Replace the id with an operation belonging to your workspace.
const response = await fetch(base.replace(/\/$/, '') + '/v1/call', {
  method: 'POST',
  // Authenticate this request with the scoped bearer key.
  headers: { Authorization: `Bearer ${key}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({"operation":"operations.read","payload":{"id":"00000000-0000-4000-8000-000000000001"}}),
  signal: AbortSignal.timeout(10000),
  redirect: 'error',
});
// Check the HTTP status before using the response.
if (!response.ok) throw new Error(`HTTP ${response.status}`);
// Use the returned JSON in your application.
const data = await response.json();
// Use data in your application; do not log private message content.

Implementation: supabase/migrations/202609170007_scoped_keys.sql

Settings

Project source: apps/web/src/review/SettingsPages.tsx

Settings use authenticated dashboard sessions. No public bearer-key settings API is documented.

No public API example is available for this page yet. Consult the source files for the current UI implementation.

Help & support

Project source: apps/web/src/review/SupportPages.tsx

Help and support are dashboard pages, not public API operations.

No public API example is available for this page yet. Consult the source files for the current UI implementation.

MailRaft Bisso Technologies Ltd · Tanzania