Developer docs
Agent Platform API
Give an AI agent scoped, bearer-key access to one tenant's services, availability, bookings, customers, and CRM — over REST or MCP.
What this is
The Mawidi Agent Platform lets an external AI agent — a voice assistant, a chat concierge, a coding or orchestration agent, or anything else that can make HTTPS calls — read and manage one tenant's data on that tenant's behalf. Every call is authenticated with a bearer API key minted from the tenant's dashboard. There is no cookie or session authority on this surface, and no CORS headers are ever emitted — the credential is a header a browser never attaches on its own.
Authentication
Every REST and MCP call carries the same bearer key. A missing, malformed, unknown, revoked, or expired key gets the same 401 response in every case, so the response alone never tells a caller which of those it was.
- Header
Authorization: Bearer mwd_live_<key>- Base URL
https://mawidi.com/api/agent/v1- Local development
http://localhost:9000/api/agent/v1
Getting a key
Keys are minted from the dashboard, not from this API. Sign in as an organization owner or admin, create a named agent client, choose its scopes, and issue a key. The full key is shown exactly once, at creation — only a prefix is shown again afterward.
Open Agent access settings →Scopes
A key's scopes are fixed at issuance and can only be narrowed or revoked afterward, never widened. Pick the narrowest set a client actually needs; a key missing a required scope gets 403 insufficient_scope.
| Scope | Used by |
|---|---|
| audit.read | GET /audit/receipts |
| availability.read | GET /availability |
| bookings.read | GET /bookings, GET /bookings/{id}, GET /bookings/changes |
| bookings.read.org | GET /bookings, GET /bookings/{id}, GET /bookings/changes |
| bookings.write | POST /bookings, PATCH /bookings/{id} |
| business_hours.read | GET /config/business-hours |
| business_hours.write | POST /config/business-hours |
| conversations.read | GET /conversations |
| customers.read | GET /customers/list |
| customers.write | POST /customers |
| knowledge.read | GET /config/knowledge |
| knowledge.write | POST /config/knowledge |
| leads.delete | DELETE /leads/{id} |
| leads.read | GET /leads, GET /leads/{id}, GET /leads/{id}/activities |
| leads.write | POST /leads, POST /leads/{id}/notes, POST /leads/{id}/stage, POST /leads/{id}/status |
| messages.send | POST /conversations/{id}/replies |
| orders.read | GET /orders |
| org_settings.read | GET /config/settings |
| org_settings.write | POST /config/settings |
| payments.link | POST /payments/links |
| payments.refund | POST /payments/refunds |
| pipeline.read | GET /pipeline/stages |
| real_estate.read | GET /properties |
| service_jobs.read | GET /service-jobs |
| services.read | GET /config/services, GET /services |
| services.write | POST /config/services |
| voice_agent.read | GET /config/voice-agent |
Operations
Every REST operation, grouped by resource. The full machine-readable contract, including request and response schemas, is the OpenAPI spec linked below.
+ = requires all of, / = requires any one of
Services
The tenant's bookable service catalogue.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /services | List bookable services | services.read |
Availability
Open slot computation, sharing the exact grid the write path enforces.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /availability | Get open slots for one service | availability.read |
Bookings
Create, read, list, reschedule, cancel, and poll changes to bookings.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /bookings | List bookings in a date range | bookings.read / bookings.read.org |
| POST | /bookings | Create a booking | bookings.write |
| GET | /bookings/{id} | Get one booking | bookings.read / bookings.read.org |
| PATCH | /bookings/{id} | Reschedule or cancel a booking | bookings.write |
| GET | /bookings/changes | Pull the booking change feed | bookings.read / bookings.read.org |
Customers
Enumeration-safe find-or-create by phone number, and the masked customer book.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| POST | /customers | Find or create a customer by phone | customers.write |
| GET | /customers/list | List the customer book | customers.read |
Orders
Order state and payment/fulfilment status. Never the tenant's Stripe handles.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /orders | List orders | orders.read |
Service Jobs
Field-service jobs, their trade and scheduled window. Never the service address.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /service-jobs | List service jobs | service_jobs.read |
Real Estate
Property listings in both languages. Never access notes or coordinates.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /properties | List property listings | real_estate.read |
Conversations
Conversation thread headers. Never message bodies.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /conversations | List conversation threads | conversations.read |
Leads
The tenant's CRM leads and their activity log. Masked contact, no free text, no email.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /leads | List leads | leads.read |
| POST | /leads | Create a lead | leads.write |
| DELETE | /leads/{id} | Propose permanently deleting a lead | leads.delete |
| GET | /leads/{id} | Get one lead | leads.read |
| GET | /leads/{id}/activities | List one lead's activity headers | leads.read |
| POST | /leads/{id}/notes | Add a note to a lead | leads.write |
| POST | /leads/{id}/stage | Move a lead to a pipeline stage | leads.write |
| POST | /leads/{id}/status | Set a lead's status | leads.write |
Pipeline
Pipeline stage configuration — no customer data to mask.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /pipeline/stages | List pipeline stage configuration | pipeline.read |
Config
Tenant configuration: service catalogue management, business hours, organization settings, the WhatsApp AI knowledge base, and a derived voice-agent summary. Every credential, billing, auth and retention field is withheld; no delete.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /config/business-hours | List business hours | business_hours.read |
| POST | /config/business-hours | Set one weekday's business hours | business_hours.write |
| GET | /config/knowledge | List knowledge-base entries | knowledge.read |
| POST | /config/knowledge | Create or update a knowledge-base entry | knowledge.write |
| GET | /config/services | List service configuration (management view) | services.read |
| POST | /config/services | Create or update a service | services.write |
| GET | /config/settings | Get organization settings | org_settings.read |
| POST | /config/settings | Update organization settings | org_settings.write |
| GET | /config/voice-agent | Get voice-agent configuration | voice_agent.read |
Audit
This API client's own per-capability usage receipts, for reconciliation and audit export. Never another client's rows, never organization-wide. No SLA/uptime reporting.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| GET | /audit/receipts | List this API client's own usage receipts | audit.read |
Messages
Replies to customers, proposed by the agent and sent only after the business owner approves each one. WhatsApp only, inside the customer's 24-hour window, never to a customer who opted out.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| POST | /conversations/{id}/replies | Propose a WhatsApp reply (sent only after owner approval) | messages.send |
Payments
Refunds and payment links for a booking, on the business's own Stripe account. Every call waits for the owner's approval after an identity check; nothing moves until then.
| Method | Path | Summary | Required scope |
|---|---|---|---|
| POST | /payments/links | Ask for a payment link for a booking (owner approval required) | payments.link |
| POST | /payments/refunds | Ask to refund a booking's or an order's payment (owner approval required) | payments.refund |
MCP endpoint
The same operations are also reachable as MCP tools over one JSON-RPC 2.0 endpoint, authenticated with the same bearer key. tools/list returns only the tools a key's scopes actually cover.
- Endpoint
/api/agent/mcp