1 OAK MLS

API Reference

Complete reference for all API endpoints in the 1 OAK MLS Platform.

API Reference

Complete reference for all API endpoints in the 1 OAK MLS Platform.


Authentication

Methods

MethodDescription
Supabase SessionCookie-based authentication via magic link or OAuth
CRON_SECRETHeader-based authentication for scheduled tasks

Role Hierarchy

member < agent < admin < owner

Higher roles inherit all permissions of lower roles.


Rate Limiting

Public routes use Upstash Redis rate limiting.

TierLimitUsed For
auth5 req/minLogin, invitations
api60 req/minGeneral API
search30 req/minSearch routes
public120 req/minPublic listing data

Rate limit headers returned:

  • X-RateLimit-Limit: Maximum requests allowed
  • X-RateLimit-Remaining: Requests remaining
  • X-RateLimit-Reset: Unix timestamp when limit resets

Public Routes

Base: /api/public Authentication: None (rate limited by IP)

EndpointMethodDescription
/api/healthGETHealth check (checks Supabase & Typesense)
/api/public/statsGETPlatform-wide listing statistics
/api/public/areasGETGet all service areas with listing counts
/api/public/areas/[slug]GETGet service area with listings
/api/contactPOSTSubmit contact form

GET /api/health

Returns service health status.

Response:

{
  "status": "ok",
  "supabase": "connected",
  "typesense": "connected",
  "timestamp": "2026-01-31T12:00:00Z"
}

GET /api/public/stats

Query Parameters:

  • workspace_id (required): Workspace identifier

Response:

{
  "total_listings": 2500,
  "active_listings": 1800,
  "workspace_count": 1
}

GET /api/public/areas

Query Parameters:

  • workspace_id (required): Workspace identifier

Response:

{
  "areas": [
    {
      "id": "uuid",
      "name": "Miami Beach",
      "slug": "miami-beach",
      "listing_count": 450
    }
  ]
}

GET /api/public/areas/[slug]

Query Parameters:

  • workspace_id (required): Workspace identifier
  • page (optional): Page number (default: 1)
  • per_page (optional): Items per page (default: 24, max: 100)
  • sort (optional): Sort field (e.g., list_price, bedrooms)

Response:

{
  "area": {
    "id": "uuid",
    "name": "Miami Beach",
    "slug": "miami-beach"
  },
  "listings": [...],
  "pagination": {
    "page": 1,
    "per_page": 24,
    "total": 450,
    "total_pages": 19
  }
}

POST /api/contact

Rate Limit: auth tier (5 req/min)

Body:

{
  "workspace_id": "uuid",
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "555-123-4567",
  "message": "I'm interested in...",
  "listing_id": "uuid (optional)"
}

Dashboard Routes (Web App)

Base: /api/dashboard Authentication: Supabase session required

User must be authenticated and have workspace membership.

Listings

EndpointMethodAuthDescription
/api/dashboard/listingsGETAllGet listings (picker/management mode)
/api/dashboard/listingsDELETEWriteBulk delete listings
/api/dashboard/listings/statsGETAllListing statistics for filters

GET /api/dashboard/listings

Query Parameters:

  • mode: picker or management
  • property_type: Filter by property type
  • status: Filter by status
  • min_price, max_price: Price range
  • page, per_page: Pagination

Photos

EndpointMethodAuthDescription
/api/dashboard/photosGETAllGet photos for a listing
/api/dashboard/photosPOSTWriteUpload photo (FormData)
/api/dashboard/photos/[id]DELETEWriteDelete photo
/api/dashboard/photos/reorderPOSTWriteReorder photos

Service Areas

EndpointMethodAuthDescription
/api/dashboard/service-areasGETAllList service areas
/api/dashboard/service-areasPOSTWriteCreate service area
/api/dashboard/service-areas/[id]GETAllGet service area
/api/dashboard/service-areas/[id]PUTWriteUpdate service area
/api/dashboard/service-areas/[id]DELETEWriteDelete service area
/api/dashboard/service-areas/reorderPOSTWriteReorder areas
/api/dashboard/service-areas/import-statusGETAllGet import status

Import Tasks

EndpointMethodAuthDescription
/api/dashboard/importsGETAllList import tasks
/api/dashboard/importsPOSTWriteCreate import task
/api/dashboard/imports/[id]GETAllGet import task
/api/dashboard/imports/[id]PATCHAgent+Update import task
/api/dashboard/imports/[id]/syncPOSTWriteTrigger sync
/api/dashboard/imports/previewPOSTWritePreview import count
/api/dashboard/imports/from-service-areasPOSTWriteBulk import

Members & Invitations

EndpointMethodAuthDescription
/api/dashboard/membersGETAdminList workspace members
/api/dashboard/members/[id]PATCHAdminUpdate member role
/api/dashboard/members/[id]DELETEAdminRemove member
/api/dashboard/invitationsGETAdminList invitations
/api/dashboard/invitationsPOSTAdminCreate invitation
/api/dashboard/invitations/[id]DELETEAdminCancel invitation

Domains

EndpointMethodAuthDescription
/api/dashboard/domainsGETAdminList custom domains
/api/dashboard/domainsPOSTAdminAdd domain
/api/dashboard/domains/[id]GETAdminGet domain details
/api/dashboard/domains/[id]PATCHAdminUpdate domain
/api/dashboard/domains/[id]DELETEAdminDelete domain

Settings & Branding

EndpointMethodAuthDescription
/api/dashboard/settingsGETAllGet workspace settings
/api/dashboard/settingsPATCHAdminUpdate settings
/api/dashboard/complianceGETAllGet compliance profile
/api/dashboard/compliancePATCHAdminUpdate compliance
/api/dashboard/brandingGETAllGet branding settings
/api/dashboard/brandingPATCHAdminUpdate branding
/api/dashboard/branding/uploadPOSTWriteUpload branding assets
/api/dashboard/heroGETAllGet hero settings
/api/dashboard/heroPOSTWriteUpload hero image
/api/dashboard/hero-videoGETAllGet hero video settings
/api/dashboard/hero-videoPOSTWriteUpload hero video
/api/dashboard/hero-video/signed-urlPOSTWriteGet signed URL for video upload
/api/dashboard/hero-video/confirmPOSTWriteConfirm video upload completion
/api/dashboard/agent-avatarPOSTWriteUpload agent avatar
/api/dashboard/agent-photoPOSTWriteUpload agent photo
/api/dashboard/brokerage-logoPOSTWriteUpload brokerage logo
/api/dashboard/team-logoPOSTWriteUpload team logo
/api/dashboard/spotlight-imagePOSTWriteUpload agent spotlight image
/api/dashboard/mls-logoGETAllGet MLS logo
/api/dashboard/uploadPOSTWriteGeneric file upload

Blog Posts

EndpointMethodAuthDescription
/api/dashboard/postsGETAllList blog posts (filterable by category, status)
/api/dashboard/postsPOSTWriteCreate a new blog post
/api/dashboard/posts/[id]GETAllGet post details
/api/dashboard/posts/[id]PATCHWriteUpdate a post (title, body, status, etc.)
/api/dashboard/posts/[id]DELETEWriteDelete a post
/api/dashboard/posts/check-slugGETAllCheck if a post slug is available

Post categories: blog, market-report, neighborhood-guide, press, just-sold Post statuses: draft, published, archived

Draft Social Posts

EndpointMethodAuthDescription
/api/dashboard/draft-postsGETAllList draft social posts (scoped to agent's personal listings)
/api/dashboard/draft-posts/countGETAllGet count of pending draft posts
/api/dashboard/draft-posts/[id]GETAllGet draft post details
/api/dashboard/draft-posts/[id]PATCHWriteUpdate draft post (edit content, change status)
/api/dashboard/draft-posts/[id]DELETEWriteDelete a draft post
/api/dashboard/draft-posts/[id]/generatePOSTWriteGenerate AI social content for a draft
/api/dashboard/draft-posts/[id]/regeneratePOSTWriteRegenerate AI content with new prompt

Draft posts are auto-created when features.autoDraftPosts is enabled and listing status changes are detected. Posts target Instagram, Facebook, and LinkedIn.

Automation Outbox

EndpointMethodAuthDescription
/api/dashboard/outboxGETAllList automation outbox items (with listing data)
/api/dashboard/outbox/countGETAllGet count of pending + generated items (for nav badge)
/api/dashboard/outbox/[id]PATCHWriteUpdate outbox item status or save edited content
/api/dashboard/outbox/[id]/generatePOSTWriteGenerate AI social content for a proposal
/api/dashboard/outbox/[id]/regeneratePOSTWriteRegenerate AI content for a generated item

Outbox items are auto-created when features.automations is enabled and listing status changes match configured automation rules. Requires AI Content Generation to be enabled with an API key configured. See Automations Reference for full details.

Media Library

EndpointMethodAuthDescription
/api/dashboard/mediaGETAllList media assets (category filter, search, pagination)
/api/dashboard/mediaPOSTWriteUpload media file (FormData, max 20 MB)
/api/dashboard/media/[id]DELETEWriteDelete a media asset
/api/dashboard/media/storageGETAllGet storage usage stats (bytes, file count)

Accepted formats: JPEG, PNG, WebP, HEIC. Categories: hero, listing, blog, branding, general.

Leads

EndpointMethodAuthDescription
/api/dashboard/leadsGETAllList contact form submissions and landing page leads
/api/dashboard/leads/[id]GETAllGet lead details
/api/dashboard/leads/statsGETAllGet lead statistics (counts, sources)

Analytics

EndpointMethodAuthDescription
/api/dashboard/analytics/overviewGETAllDashboard overview (views, leads, top listings)
/api/dashboard/analytics/listing-viewsGETAllListing page view data (with date range)
/api/dashboard/analytics/lead-sourcesGETAllLead source breakdown (UTM tracking)

AI Content Generation

EndpointMethodAuthDescription
/api/dashboard/ai/contentPOSTAgent+Generate AI content (generic)
/api/dashboard/ai/listing-descriptionPOSTAgent+Generate AI listing description
/api/dashboard/ai/listing-socialPOSTAgent+Generate AI social media captions
/api/dashboard/ai/listing-emailPOSTAgent+Generate AI email marketing copy
/api/dashboard/ai/generate-blog-postPOSTAgent+Generate AI blog post content
/api/dashboard/ai/generate-blocksPOSTAgent+Generate AI website content blocks
/api/dashboard/ai/usageGETAllGet workspace AI usage stats

All AI routes require features.aiContentGeneration to be enabled.

Status Changes

EndpointMethodAuthDescription
/api/dashboard/status-changesGETAllGet recent listing status changes (scoped to agent's personal listings)

Returns listing transitions like new listings, price changes, status changes (Active→Pending→Closed), and delisted events.

Page-Specific Hero & Video

EndpointMethodAuthDescription
/api/dashboard/pages/[slug]/heroGETAllGet page-specific hero config
/api/dashboard/pages/[slug]/heroPOSTWriteUpload page hero image
/api/dashboard/pages/[slug]/hero-videoPOSTWriteUpload page hero video
/api/dashboard/pages/[slug]/hero-video/signed-urlPOSTWriteGet signed URL for page video upload
/api/dashboard/pages/[slug]/hero-video/confirmPOSTWriteConfirm page video upload

Supported page slugs: about, contact, listings, blog.

MLS Connection

EndpointMethodAuthDescription
/api/dashboard/mls-connectionGETAllGet MLS connection status
/api/dashboard/mls-connection/testPOSTWriteTest MLS connection

Landing Pages

EndpointMethodAuthDescription
/api/dashboard/landing-pagesGETAllList landing pages
/api/dashboard/landing-pagesPOSTWriteCreate a landing page
/api/dashboard/landing-pages/[id]GETAllGet landing page details
/api/dashboard/landing-pages/[id]PATCHWriteUpdate a landing page
/api/dashboard/landing-pages/[id]DELETEWriteDelete a landing page
/api/dashboard/landing-pages/check-slugGETAllCheck slug availability

Requires features.landingPages to be enabled.

Account & Dashboard Home

EndpointMethodAuthDescription
/api/dashboard/accountGETAllGet current user account info
/api/dashboard/homeGETAllGet dashboard home data (stats, recent activity)

Listing Utilities

EndpointMethodAuthDescription
/api/dashboard/featured-listings/togglePOSTWriteToggle a listing's featured status
/api/dashboard/listings/[id]/primary-photoPOSTWriteSet a listing's primary photo
/api/dashboard/listings/statsGETAllGet listing statistics

Sync Management

EndpointMethodAuthDescription
/api/dashboard/imports/sync-allPOSTWriteTrigger sync for all enabled tasks
/api/dashboard/sync/runs/[runId]/cancelPOSTWriteCancel a running sync

System Health

EndpointMethodAuthDescription
/api/dashboard/system-health/repair-indexPOSTWriteRepair Typesense index for workspace

Billing

EndpointMethodAuthDescription
/api/billing/checkoutPOSTAdminCreate Stripe Checkout Session
/api/billing/portalPOSTAdminCreate Customer Portal session
/api/billing/subscriptionGETMemberGet subscription status and access

POST /api/billing/checkout

Creates a Stripe Checkout Session for subscribing to a plan. Redirects user to Stripe-hosted checkout.

Rate limit: auth tier (5 req/min)

Body:

{
  "plan": "professional",
  "interval": "year"
}

Response:

{
  "url": "https://checkout.stripe.com/c/pay/..."
}

POST /api/billing/portal

Creates a Stripe Customer Portal session for managing billing.

Rate limit: auth tier (5 req/min)

Response:

{
  "url": "https://billing.stripe.com/p/session/..."
}

GET /api/billing/subscription

Returns the current subscription, access state, AI usage, and available upgrades.

Rate limit: api tier (60 req/min)

Response:

{
  "subscription": {
    "plan": "professional",
    "status": "active",
    "billingInterval": "year",
    "currentPeriodEnd": "2027-02-25T00:00:00Z",
    "cancelAtPeriodEnd": false,
    "isOverride": false,
    "overrideReason": null
  },
  "access": {
    "plan": "professional",
    "status": "active",
    "isActive": true,
    "isPastDue": false,
    "isOverride": false,
    "features": { "maxListings": 5000, "blog": true, "..." : "..." }
  },
  "availableUpgrades": ["prestige"],
  "aiUsageCount": 42,
  "role": "owner"
}

Webhook

EndpointMethodAuthDescription
/api/webhooks/stripePOSTStripe signatureStripe webhook handler

Handles: checkout.session.completed, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, invoice.payment_succeeded, invoice.payment_failed


Admin Routes (Admin App)

Base: /api/admin Authentication: Supabase session + workspace membership with minimum role

Workspaces

EndpointMethodMin RoleDescription
/api/admin/workspacesPOSTMemberCreate workspace
/api/admin/workspaces/[id]GETMemberGet workspace details
/api/admin/workspaces/[id]PATCHAdminUpdate workspace
/api/admin/workspaces/check-slugGETMemberCheck slug availability

POST /api/admin/workspaces

Body:

{
  "name": "My Realty",
  "slug": "my-realty",
  "owner_email": "owner@example.com"
}

Workspace Listings

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/listingsGETMemberList listings
/api/admin/workspaces/[id]/listingsDELETEAdminBulk delete (max 100)
/api/admin/workspaces/[id]/listings/statsGETMemberListing stats
/api/admin/workspaces/[id]/listings/agent-syncPOSTAdminTrigger agent sync
/api/admin/workspaces/[id]/listings/my-listingsGETMemberGet user's listings

GET /api/admin/workspaces/[id]/listings

Query Parameters:

  • property_type: Filter by type
  • status: Filter by StandardStatus
  • import_task_id: Filter by import task
  • page, per_page: Pagination
  • sort, order: Sorting

MLS Connection

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/mlsPOSTAdminCreate MLS connection
/api/admin/workspaces/[id]/mlsPATCHAdminUpdate MLS connection
/api/admin/workspaces/[id]/mls/testPOSTAdminTest connection

POST /api/admin/workspaces/[id]/mls

Body:

{
  "base_url": "https://api.bridgedataoutput.com/api/v2/OData",
  "dataset_id": "mfr_reso",
  "access_token": "your-bridge-token"
}

Import Tasks

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/importsGETMemberList import tasks
/api/admin/workspaces/[id]/importsPOSTAdminCreate import task
/api/admin/workspaces/[id]/imports/[taskId]GETMemberGet task details
/api/admin/workspaces/[id]/imports/[taskId]PATCHMemberUpdate task
/api/admin/workspaces/[id]/imports/[taskId]DELETEAdminDelete task
/api/admin/workspaces/[id]/imports/[taskId]/runPOSTAdminRun task
/api/admin/workspaces/[id]/imports/[taskId]/togglePOSTAdminEnable/disable task
/api/admin/workspaces/[id]/imports/preview-countPOSTAdminPreview count

POST /api/admin/workspaces/[id]/imports

Body:

{
  "name": "Miami Beach Active",
  "filter": "City eq 'Miami Beach' and StandardStatus eq 'Active'",
  "cadence": "hourly",
  "max_records": 500,
  "enabled": true
}

POST /api/admin/workspaces/[id]/imports/[taskId]/run

Body:

{
  "mode": "incremental"  // or "full"
}

Timeout: 300 seconds

Sync Management

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/sync/runPOSTAdminRun full workspace sync
/api/admin/workspaces/[id]/sync/runsGETMemberList sync runs
/api/admin/workspaces/[id]/sync/runs/[runId]GETMemberGet sync run details
/api/admin/workspaces/[id]/sync/runs/[runId]/cancelPOSTAdminCancel running sync

Field Mapping

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/mappingGETMemberGet field mapping
/api/admin/workspaces/[id]/mappingPOSTAdminCreate/update mapping
/api/admin/workspaces/[id]/mapping/validatePOSTAdminValidate mapping
/api/admin/workspaces/[id]/mapping/[versionId]/restorePOSTAdminRestore version

Members & Invitations

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/membersGETMemberList members
/api/admin/workspaces/[id]/membersPOSTAdminAdd member
/api/admin/workspaces/[id]/members/[memberId]GETMemberGet member
/api/admin/workspaces/[id]/members/[memberId]PATCHAdminUpdate member
/api/admin/workspaces/[id]/members/[memberId]DELETEAdminRemove member
/api/admin/workspaces/[id]/invitationsGETMemberList invitations
/api/admin/workspaces/[id]/invitationsPOSTAdminCreate invitation
/api/admin/workspaces/[id]/invitations/[invitationId]GETMemberGet invitation
/api/admin/workspaces/[id]/invitations/[invitationId]PATCHAdminResend invitation
/api/admin/workspaces/[id]/invitations/[invitationId]DELETEAdminCancel invitation

Workspace Configuration

EndpointMethodMin RoleDescription
/api/admin/workspaces/[id]/domainsGETMemberList domains
/api/admin/workspaces/[id]/domainsPOSTAdminAdd domain
/api/admin/workspaces/[id]/domains/[domainId]PATCHAdminUpdate domain
/api/admin/workspaces/[id]/domains/[domainId]DELETEAdminDelete domain
/api/admin/workspaces/[id]/complianceGETMemberGet compliance
/api/admin/workspaces/[id]/compliancePATCHAdminUpdate compliance
/api/admin/workspaces/[id]/settingsGETMemberGet settings
/api/admin/workspaces/[id]/settingsPATCHAdminUpdate settings

Billing Override (Platform Admin)

EndpointMethodAuthDescription
/api/admin/workspaces/[id]/billingGETPlatform AdminGet subscription + Stripe customer
/api/admin/workspaces/[id]/billingPOSTPlatform AdminGrant/revoke billing override

POST /api/admin/workspaces/[id]/billing

Body:

{
  "is_billing_override": true,
  "plan": "prestige",
  "override_reason": "Charter partner — founding client"
}

AI Routes (Web App)

Base: /api/dashboard/ai Authentication: Supabase session + workspace membership

Requires workspace.settings.features.aiContentGeneration to be enabled.

Full route list is documented in the AI Content Generation section under Dashboard Routes.

POST /api/dashboard/ai/generate-blocks

Generates website content blocks (hero text, value props, about sections) using AI with automatic Fair Housing compliance checks.

Body:

{
  "agentName": "Jane Smith",
  "brokerage": "Luxury Homes Realty",
  "serviceAreas": ["Miami Beach", "Coral Gables"],
  "specialty": "luxury waterfront properties"
}

Response:

{
  "blocks": {
    "hero": "Your Luxury Miami Waterfront Expert",
    "valueProps": ["..."],
    "about": "..."
  },
  "fairHousingCheck": {
    "passed": true,
    "flaggedTerms": []
  },
  "usage": {
    "inputTokens": 250,
    "outputTokens": 800,
    "costCents": 2
  }
}

GET /api/dashboard/ai/usage

Response:

{
  "currentMonth": {
    "totalGenerations": 15,
    "totalInputTokens": 3750,
    "totalOutputTokens": 12000,
    "totalCostCents": 30
  },
  "tier": "free",
  "tierLimit": 50,
  "remaining": 35
}

Invitation Routes (Web App)

Base: /api/invitations Authentication: Supabase session required

EndpointMethodRate LimitDescription
/api/invitationsGET-Get pending invitations
/api/invitations/[token]/acceptPOSTauth (5/min)Accept invitation
/api/invitations/[token]/declinePOSTauth (5/min)Decline invitation

Workspace Discovery (Web App)

Base: /api/workspaces Authentication: Supabase session required

EndpointMethodDescription
/api/workspacesGETList user's workspaces

Cron Routes (Admin App)

Base: /api/cron Authentication: CRON_SECRET header

EndpointMethodDescription
/api/cron/syncGETRun scheduled syncs

GET /api/cron/sync

Headers:

Authorization: Bearer {CRON_SECRET}

Runs syncs for all enabled import tasks based on their cadence settings.

Response:

{
  "results": [
    {
      "workspace": "lainey-levin",
      "import_task_id": "uuid",
      "status": "success",
      "records_fetched": 50
    }
  ]
}

Auth Routes (Admin App)

EndpointMethodDescription
/api/auth/callbackPOSTOAuth callback handler

Common Response Formats

Success Response

{
  "data": { ... },
  "meta": {
    "page": 1,
    "per_page": 24,
    "total": 150
  }
}

Error Response

{
  "error": "Error message",
  "code": "ERROR_CODE",
  "details": { ... }
}

Pagination

{
  "data": [...],
  "pagination": {
    "page": 1,
    "per_page": 24,
    "total": 150,
    "total_pages": 7,
    "has_next": true,
    "has_prev": false
  }
}

HTTP Status Codes

CodeMeaning
200Success
201Created
204No Content (successful deletion)
400Bad Request (validation error)
401Unauthorized (not authenticated)
403Forbidden (insufficient permissions)
404Not Found
409Conflict (duplicate resource)
429Too Many Requests (rate limited)
500Internal Server Error

On this page