API Overview

SendHub.ai is built on Supabase — your API is a fully typed PostgreSQL REST API with real-time subscriptions and row-level security out of the box.

You can interact with your SendHub data in two ways:

MethodBest for
Supabase ClientApps, integrations, dashboards — full type safety, realtime, any language
MCP ServerConnecting AI agents (Claude, Codex, Gemini, Cursor)

Install the Supabase Client

npm install @supabase/supabase-js

Initialize

Your API Secret Key is available in the SendHub dashboard under API Keys.

import { createClient } from '@supabase/supabase-js'

const API_SECRET_KEY = 'your-api-secret-key' // from Dashboard → API Keys

const sendhub = createClient(
  'https://noddeqgxbyujhpqxezbg.supabase.co',
  'sb_publishable_YVA7_HVuhhguR-OVA-LZPg_ecJF2CY2',
  { global: { headers: {
    Authorization: `Bearer ${API_SECRET_KEY}`
  }}}
)

// All queries are scoped to your org automatically
const { data } = await sendhub
  .from('conversations')
  .select('id, status, last_message_at, contacts(name, phone)')
  .eq('status', 'ai_handling')
  .order('last_message_at', { ascending: false })

TypeScript Types (Optional)

If you’re using TypeScript, you can generate types for full autocomplete and type safety:

npx supabase gen types --lang typescript \
  --project-id noddeqgxbyujhpqxezbg > types.ts

Schema changes are announced in the SendHub dashboard. When the schema changes, re-run this command to keep your types in sync.

Data Model

Organization (billing, plan, team)
  └── Business / Workspace (AI config, channels, contacts)
        ├── Channel (WhatsApp number — business or personal)
        ├── Contact (WhatsApp user)
        └── Conversation (thread between contact + channel)
              └── Message (individual message with delivery tracking)
ConceptTableDescription
OrganizationorganizationsTop-level tenant. Owns billing, plan limits, team members.
WorkspacebusinessesA workspace within an org. Has its own AI config, channels, contacts.
ChannelchannelsA connected WhatsApp number (business API or personal bridge).
ContactcontactsA WhatsApp user who has messaged your channels.
ConversationconversationsAn ongoing thread on a specific channel with a specific contact.
MessagemessagesIndividual message — inbound or outbound, with delivery status and AI metadata.
Team Memberteam_membersA user with access to the org (owner, admin, or agent).
API Secret Keyapi_keysProgrammatic access keys with scoped permissions.

Row-Level Security

Every table has RLS policies. Queries are automatically scoped to your organization — you can only access data where you’re a team member. No manual org filtering needed.

Quick Examples

// List all conversations with AI handling
const { data } = await sendhub
  .from('conversations')
  .select('*, contacts(name, phone), channels(label)')
  .eq('status', 'ai_handling')

// Send a message
await sendhub.from('messages').insert({
  conversation_id: 'uuid',
  business_id: 'uuid',
  org_id: 'uuid',
  direction: 'outbound',
  sender_type: 'agent',
  content: 'Your order has shipped!'
})

// Subscribe to new messages in real-time
sendhub
  .channel('inbox')
  .on('postgres_changes', {
    event: 'INSERT',
    schema: 'public',
    table: 'messages',
  }, (payload) => console.log('New:', payload.new))
  .subscribe()

Next Steps