Developer Portal

Programmatic API & AI Agents

Run your workspace from any AI or system: an MCP server for Claude, ChatGPT and Gemini, and a REST API for integrations — sales, products, inventory, invoicing, content and the inbox.

Built for AI assistants — Claude, ChatGPT, Gemini

MCP Protocolllms.txt standard

Paste one URL into your AI app and sign in: Nine's MCP server gives it 86 tools across sales, products, inventory, invoicing, content and the inbox — also described as OpenAPI 3 and llms.txt.

Gemini app setup

  1. 1. Open Gemini → Settings → Connected apps → Custom apps → Add a custom app.
  2. 2. Enter the MCP server URL:
    https://app.ninehoang.com/mcp
  3. 3. Click Next and approve the connection in Nine — there is no client ID or secret to enter.

MCP tools

Tool NameDescriptionParameters
get_workspaceWhich workspace this connection belongs to, and whether it may write.none
list_sales_ordersOrders, newest first, with customer, status and totals — before tax, tax, total, cost and profit.search?, status?, customer_id?, start_date?, end_date?, limit?, offset?
create_sales_orderRecord a sale from products and quantities; names, prices and taxes come from the catalogue. Confirm it in the same call if you like.lines [{ product_id, quantity, unit_price?, discount_percent? }], customer_id?, ordered_at?, note?, confirm?
confirm_sales_orderConfirm a draft: its cost is fixed and goods leave stock — or a delivery is created, with Inventory installed.id
sales_reportRevenue before tax, cost of goods sold and gross profit for any period, with the top products and customers.start_date?, end_date?, top?
list_productsThe catalogue with category, cost and sales price, margin per unit, taxes and quantity on hand.search?, category_id?, kind?, include_archived?, limit?, offset?
create_productAdd a product or service with its prices, taxes, tracking and opening stock.name, kind?, category_id?, tracking?, sales_price?, cost_price?, sales_tax_ids?, purchase_tax_ids?, quantity?
list_replenishmentReorder rules with on hand, incoming, outgoing, forecast — and how much to order.product_id?, warehouse_id?, to_order_only?
create_invoiceA customer invoice or a vendor bill, with lines; post it to give it its number.kind, partner_id?, reference?, invoice_date?, due_date?, lines?, post?, note?
record_invoice_paymentRecord money received or paid against a posted invoice or bill.invoice_id, amount, method_id, received_at?, note?
list_entriesA collection's entries — blog posts, services, projects — in every language, with fields, categories, tags and status.collection, status?, limit?, offset?
create_entryA new draft in any collection, in one language; its article is written next, as Markdown.collection, title, locale?, slug?, summary?, fields?, parent_id?
set_articleWrite one language of an entry's article as Markdown — headings, lists, callouts, galleries, embeds.kind, id, locale, markdown
publish_articlePublish a draft now or at a set time, or take it off the site — when the workspace lets assistants publish.kind, id, action?, at?
list_messagesLeads from the website's contact form, newest first, with where each stands in triage.status?, search?, limit?, offset?
create_manyUp to 50 records of any types in one call — one approval. A later item can use an earlier one's result: "$0.id".items [{ tool, arguments }]

Authentication

AI apps connect with OAuth 2.1: sign in, choose a workspace and an access level. Integrations send a workspace token on every request — Authorization: Bearer nh_ws_…. Nothing expires on its own, and revoking ends access at once.

1. Read rows — any table, with filters, order and paging
curl "https://app.ninehoang.com/api/v1/sales_orders?select=*&order=ordered_at.desc&limit=20" \
  -H "Authorization: Bearer nh_ws_YOUR_API_TOKEN"
2. Run an action — the same rules the MCP server applies
curl -X POST "https://app.ninehoang.com/api/v1/tools/confirm_sales_order" \
  -H "Authorization: Bearer nh_ws_YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "ORDER_UUID"}'

SDK & Client Quickstart

Connect to your workspace using standard HTTP clients, the JavaScript/TypeScript SDK, or Python.

# 1. Read rows — any table, with PostgREST filters
curl "https://app.ninehoang.com/api/v1/sales_orders?select=*&order=ordered_at.desc&limit=20" \
  -H "Authorization: Bearer nh_ws_YOUR_API_TOKEN"

# 2. Run an action — the same rules the MCP server applies
curl -X POST "https://app.ninehoang.com/api/v1/tools/confirm_sales_order" \
  -H "Authorization: Bearer nh_ws_YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id": "ORDER_UUID"}'

Resource Endpoints & Schemas

Every table through PostgREST's query language, and every business step through /api/v1/tools — both scoped to the token's workspace by row-level security.

GETPOSTPATCHDELETE
/api/v1/expenses_transactions
Workspace expense ledger, spending records, and day-to-day outlays.
FieldTypeDescription / Valid Options
iduuidPrimary key identifier
nametextExpense description / item (max 255 chars)
amountnumericAmount in workspace currency
category_idenumOptions: 'food-drinks', 'entertainment', 'local-transport', 'clothing', 'beauty-care', 'sports', 'essentials', 'fixed-expenses', 'credit-repayment', 'installment-payment', 'family-support', 'travel', 'work-expenses', 'investments', 'other'. Read from `transaction_categories` (the rows offered to Expenses), so this list can grow without a deploy.
method_idenumSlugs from the transaction_methods table: 'cash', 'bank-transfer', 'mobile-wallet', 'credit-card', 'installment'. Read the live list from /openapi.json.
occurred_attimestamptzDate and time of transaction
notetextOptional context or memo

HTTP status codes

From the API itself, errors are { error } in words; from a table endpoint, PostgREST's { code, message }.

200 OK

Rows read, updated or deleted, or an action's result.

201 Created

Rows created through POST /api/v1/{resource}; the created rows come back.

400 Bad Request

An action refused its arguments — { error } says why, in words — or a malformed filter or payload.

401 Unauthorized

Missing, revoked or expired token, or the workspace's API switched off. AI apps reconnect through OAuth.

403 Forbidden

A read-only token tried to write, or the app that owns the data is not installed.

404 Not Found

No such resource or action; GET /api/v1 and GET /api/v1/tools list them.

Tenant Isolation & Security

Every API request is scoped by Postgres Row Level Security (RLS) via public.api_workspace_id(). System credentials and internal auth settings are completely inaccessible.

Zero Cross-Tenant LeakPostgres RLS filters every table query automatically by workspace ID.
Excluded TablesWorkspace members, passwords, billing, and credentials are completely ungranted.
Instant kill switchTurning off the workspace API switch, or revoking one token, ends access on the next request — AI apps get a 401 and offer to reconnect.

Ready to connect your workspace?

Generate and manage tokens with fine-grained read or read-write permissions directly inside your Workspace Settings.

Go to Workspace API Settings