DISCOVERY TIER 1 of 3 — the service directory: one token-dense line per service (s:name st:status cost:class ops:N — purpose). START HERE instead of reading every tool. No auth required. NEXT: simpler.describe_service with a service name from the listing.
无需输入参数。
DISCOVERY TIER 2 of 3 — one service's operations and entity shapes from the live catalog, token-dense (op lines name the underlying tool). No auth required. NEXT: simpler.invoke {service, operation, args} — or call the named tool directly.
输入参数service必填
DISCOVERY TIER 3 of 3 — execute one operation: dispatches to the underlying generated tool (same gates, same envelope, same idempotency as calling it directly). Requires auth. args = the underlying tool's arguments object.
输入参数argsservice必填operation必填
DISCOVERY TIER 0 — the OUTCOME MENU: one line per common business outcome, each mapped to ONE tool with one-call notes (composites: ONE call creates the whole document). START HERE for a business task. No auth required. NEXT: call the named tool directly, or simpler.directory for the full catalog.
无需输入参数。
Check a parked approval by approval_id (returned in an APPROVAL_REQUIRED refusal). States: pending (the account owner has not decided — tell the user, do NOT retry the original call), executed (done — the result rides this response; never re-run the call; an approved invoice_share or quote_share keeps no link or document here, so read the current link with that tool and action 'get' as result.link_not_stored.next_call says), rejected / expired / failed (terminal — re-compose only if the user asks again). Scoped to the granting user's approvals.
输入参数approval_id必填
agent_note_send_cross_tenant
Send a cross-tenant AI-to-AI message into another tenant's agent_note inbox — the door that turns a cross_tenant_comm consent grant into an actual reach. Both tenants must be KYB-approved and the recipient must hold an active grant (claims can narrow it further); every recipient-side failure refuses identically so the network can't be probed for who exists — only your OWN unapproved KYB answers distinctly, since that discloses nothing about the target. Your sender identity is injected server-side into from_tenant_id and cannot be spoofed. NEXT: agent_note_list on the recipient side confirms delivery.
输入参数bodystatussubjectto_tenant_id必填from_tenant_idconsent_grant_idrelated_entity_idrelated_entity_type
Create-or-merge a contact keyed on email-then-phone identity — the sync door the future desktop harness and ingest lanes write through. Matching probes email first, then phone; a hit MERGES only the fields you send (omitted fields keep their stored values, so a partial sync payload can never wipe a curated field), a miss creates. Status moves still obey the transition machine — an upsert cannot jump straight to vip. Accepts the same first-note/first-interaction composite children as contact_create.
输入参数namenotetagsemailnotesphonesourcestatusaddresscompanyinteractionlast_contact_at另有 1 个
Logs a new expense — amount_cents must be integer CENTS (a decimal string via `amount` also works, and `category` resolves to a category_id by name). A same-amount, same-UTC-day duplicate for the same user is refused as CONFLICT unless you resend identically with force: true. Status is honor-or-refuse: admin/owner creators land 'approved' by default (or may request it explicitly), everyone else always starts 'draft'. NEXT: expense_submit sends a draft into the approval queue.
输入参数costdateforcenotestotalamountstatusvendorcategorycurrencyocr_jsontax_type另有 17 个
Sends your own draft expense into the approval queue — draft only; an already-submitted or resolved expense refuses CONFLICT, and only the expense's own creator may submit it. Nobody is notified automatically — approvers see it appear in the Team Claims view. NEXT: expense_approve or expense_reject (admin/owner).
输入参数id必填notesstatusvendorcurrencyocr_jsontax_typetags_jsonapproved_atapproved_bycategory_idreceipt_key另有 10 个
Approves a submitted expense claim — requires the admin or owner role, and only a 'pending' expense qualifies (CONFLICT otherwise). Stamps approved_by and approved_at with the caller and the current time; once approved, the row's content freezes for everyone except the approver themselves. NEXT: expense_reimburse (owner only) to pay it out.
输入参数id必填notesstatusvendorcurrencyocr_jsontax_typetags_jsonapproved_atapproved_bycategory_idreceipt_key另有 10 个
Log an interaction — call, meeting, email, message, visit, payment, or other — against a contact. The ONE activity-logging door every lane funnels through, so the contact's last_contact_at freshness bumps no matter which surface logged the touch; the bump never moves backward, so importing older history can never regress a fresher touch. Accepts contact_name, contact_email or contact_phone in place of contact_id. NEXT: contact_read to see the bumped last_contact_at.
输入参数summarycontact_idsource_refoccurred_atcontact_namecontact_emailcontact_phoneinteraction_type
ONE call creates the whole document: claims the next invoice number, then writes the header plus every line in `items` ([{description, quantity, unit_price_cents}], integer CENTS). client_name finds a client by name or creates one. Birth status 'paid' needs items in the same call. tax_scheme sg_gst or my_sst taxes each line by its tax_code (refusals: see tax_scheme). When present, the second content block is the invoice as copy-ready text, shown with a Copy button where the host draws MCP Apps; if the user says they cannot see the invoice, give them that block word for word; share:true adds a client link, only when the user asks for one. NEXT: invoice_payment_record to record money-in.
输入参数forceitemsnotessharestatuspaid_atsent_atcurrencydue_datecash_saleclient_idsource_id另有 13 个
invoice_adjustment_record
[REQUIRES APPROVAL] Records a credit note, write-off or post-issue discount on an issued invoice. A credit_note is numbered from the credit note series, holds its tax at the invoice's rate and takes reason_code and credit_outcome: reduce_balance (default) lowers what is owed; refunded_outside records a refund the business made outside Simpler, moves no money and is how a 'paid' invoice gets one. write_off and discount_post_issue need a 'sent' invoice. Money is integer CENTS (amount_cents) or a decimal STRING (amount); caps: see preconditions. Refuses a draft, a cancelled invoice, an amount over its cap and dispute_settlement; each refusal names the fix. An agent's call parks for approval. NEXT: invoice_read.
输入参数amountreasonpartialcurrencyinvoice_idoccurred_atreason_codeamount_centscredit_outcomeinvoice_numberadjustment_type
Records a money-in fact row against an invoice (by invoice_id or its invoice_number) in ONE call: money is integer CENTS via amount_cents, or a decimal STRING via amount — never multiply or divide yourself. A draft invoice auto-advances to 'sent'; a cancelled invoice refuses; an amount above the remaining balance refuses unless allow_overpayment is true. status 'paid' derives from the ledger this writes, so this is how an invoice becomes paid. A same invoice/amount/day repeat refuses as a likely duplicate unless resent with force:true. NEXT: invoice_read to read it back.
输入参数noteforceamountmethodcurrencyinvoice_idoccurred_atamount_centsinvoice_numberallow_overpayment
myinvois_invoice_generate
Mint a sealed LHDN e-invoice in ONE call: invoice_type, line_items (unit_price_cents in integer CENTS, tax_rate_bps in basis points), and a buyer as customer_id or an inline buyer object. Refuses until myinvois_settings_save is done; invoice_type 02/03/04 also needs original_invoice_id naming a type-01 invoice with a recorded LHDN UUID, checked BEFORE the number is claimed, so a rejected note never burns a number. The result is immutable and carries portal_field_sheet; Simpler never submits it to LHDN. NEXT: the owner keys the field sheet into the MyInvois portal form, then myinvois_invoice_record_submission with the UUID the portal assigns.
输入参数buyernotesstatuscurrencybuyer_tinlhdn_uuidtax_centsbuyer_nameissue_dateline_items必填customer_idtotal_cents另有 10 个
myinvois_invoice_record_submission
Record the UUID the LHDN MyInvois portal assigned after the owner keyed this e-invoice into the portal (its form or LHDN's Excel batch template). Simpler never submits to LHDN and never calls the MyInvois API; this only stores the UUID the owner copies back. Only a type-01 original accepts a UUID: credit, debit and refund notes are refused (they link through BillingReference), so record the UUID on the original instead. Moves status generated to submitted; calling it again on a submitted invoice corrects a mistyped UUID. NEXT: myinvois_invoice_read to see the UUID attached.
输入参数id必填statuscurrencybuyer_tinlhdn_uuidtax_centsbuyer_nameissue_datecustomer_idtotal_centsinvoice_datainvoice_type另有 5 个
Read one sealed e-invoice by id, with its portal_field_sheet: the document's values laid out to key into the LHDN MyInvois portal form (e-invoice details, supplier, buyer, each line, totals), coded values with their meaning. Simpler never submits to LHDN; portal_field_sheet.portal_routes names the two portal routes (the online form and LHDN's Excel batch template). Refuses an id outside your tenant with NOT_FOUND: call myinvois_invoice_list for valid ids. NEXT: after the portal accepts it, myinvois_invoice_record_submission with the UUID it assigns.
输入参数id必填
ONE call creates the whole document: claims the next atomic quote number, then writes the header plus every line in `items` ([{description, quantity, unit_price_cents}], integer CENTS) together. client_name resolves an existing client by name or creates one. tax_scheme sg_gst or my_sst taxes each line by its tax_code (refusals: see tax_scheme). When present, the second content block is the quote as copy-ready text, shown with a Copy button where the host draws MCP Apps; if the user says they cannot see the quote, give them that block word for word; make a client link with quote_share only when the user asks for one. NEXT: quote_convert to turn the quote into its invoice.
输入参数forceitemsnotesstatuscurrencyclient_idissue_dateline_itemstax_schemeclient_namevalid_untilquote_number另有 3 个
Converts a quote into its invoice in ONE call: claims the quote's 'converted' status first (so a lost race never creates an orphan invoice), copies every live line item across, and records converted_invoice_id — nothing else to do afterward. Refuses if the quote is already converted (the error carries converted_invoice_id) or declined (revive it with quote_update first), and refuses with nothing converted when the quote or its lines changed while it was converting (for example a quote_item call running at the same time): read the quote again with quote_read, then convert. NEXT: invoice_read on the new invoice.
输入参数id必填notesstatuscurrencyquote_idclient_idissue_datetax_schemevalid_untilquote_numbertax_rate_bpsprices_include_tax另有 1 个
settlement_proposal_propose_cross_tenant
Record a payment obligation against a KYB-verified partner tenant's settlement_proposals — the record-don't-move on-ramp: this writes the row only, no money moves until a later settlement-rails door executes it. amount_cents is a nonzero integer CENTS (positive = you owe them, negative = a refund/reversal record) and currency must be a 3-letter code. Requires the payee's cross_tenant_settlement consent grant and both sides KYB-approved; payee-side failures refuse identically to block probing, but your OWN unapproved KYB answers distinctly. Your tenant is injected as payer_tenant_id and cannot be spoofed. NEXT: settlement_proposal_accept moves it to accepted on the payee side.
输入参数statuscurrencyaccepted_atdescriptionamount_centsto_tenant_id必填payer_tenant_idconsent_grant_idrelated_entity_idrelated_entity_type
Create a sticky_note.
输入参数colorwidthheightcontent必填z_indexposition_xposition_ytriggers_at
Move stock in or out by id or item name, in one atomic write with its movements-ledger row: stock-out clamps at zero (never negative) and applied_quantity reports what actually moved. An unmatched name CREATES the item at quantity 0 first so the delivery still lands as an audited ledger row; a name matching multiple active items refuses with the candidate ids. Concurrent adjusts on the same item retry instead of losing a write. NEXT: stock_item_list to see the item's updated balance in the full inventory.
输入参数idnametype必填unitnotesreasoncategoryquantity必填is_activeitem_nameexpiry_dateoccurred_at另有 3 个
[REQUIRES APPROVAL] Delegates a task to a teammate (or yourself) as a new team_assignment; status is workflow-owned and always starts 'pending' — passing status yourself fails validation instead of being silently overridden. Accepts natural language for the common fields: task_name/task for title, due_date/due for due_at ('YYYY-MM-DD', epoch millis, 'today', 'tomorrow', or 'next <weekday>'), and 'self'/'me'/'yourself' for assigned_to. assigned_to must already be a member of your tenant. NEXT: team_assignment_accept, then _start and _complete, drive the lifecycle from there.
输入参数duetasktitledue_atstatusdue_dateprioritytask_namestarted_ataccepted_atartifact_idassigned_to另有 13 个
Create a workflow — an AI operator's job: validates definition_json (a { nodes, edges, schedule? } graph) against the platform's node vocabulary, refusing unknown node types and any comms/message-shaped step that isn't a prepare_output node, since the platform prepares outputs but never sends them. trigger_type 'schedule' requires a schedule block; next_run_at is then computed server-side from it, never from a caller value. is_active defaults to 0 (draft) — going live is a separate explicit choice. NEXT: workflow_update to fix a rejected definition or flip is_active.
输入参数nameis_activerole_namedescriptionnext_run_attrigger_typeimported_fromdefinition_json
workflow_prepared_outputs
List this tenant's APPROVED prepared outputs: drafts a workflow's prepare_output nodes parked for review, which a human then approved in the platform inbox. Pending and rejected drafts never appear here — approval happens only in the inbox, never through this call. Optional limit 1-100 (default 50), newest-decided first. This is the platform-prepares-never-sends handoff: the desktop harness pulls approved drafts here and sends them locally.
输入参数namelimitis_activerole_namedescriptionnext_run_attrigger_typeimported_fromdefinition_json
Your prepaid wallet, period spend, caps, and runway as a compact line DSL (~8 lines). Requires auth (your balance is closed data). Read this BEFORE committing paid actions; pair with ai.estimate_cost to price a specific call first.
无需输入参数。
Price an AI task BEFORE running it: provider passthrough at wholesale cost, no markup — the per-token platform fee is retired, so text/reasoning passes through at cost. Anonymous — open catalog includes open pricing. Returns integer micro-USD plus a USD total. NEXT: run the action, then ai.budget to watch the runway.
输入参数task必填tokens_intokens_out
Who owes you, by client: each client's unpaid balance aged by days past its due date — current (not yet due), 1-30, 31-60, 61-90 and over 90 days — counted in the business's own days (the sales_settings time zone), so an invoice due today is still current. Only issued invoices with a balance left count: drafts, cancelled, paid, written-off and fully credited invoices never do. Money is integer CENTS in each invoice's own currency: one row per client per currency, and totals has one row per currency, never converted or added across currencies; read the figures as given, never multiply or divide them yourself. Clients come oldest past-due first. Optional client_id ages one client; an id that is not one of your clients is refused NOT_FOUND (find it with invoice_client_search or invoice_client_list). A limit outside 1-200 is refused VALIDATION_ERROR (leave it out for 50; totals always cover every client). NEXT: invoice_list with state 'overdue' lists the past-due invoices themselves.
输入参数limitclient_id
Show one invoice, quote or receipt as the document itself. When the result has a second content block, it is the document as copy-ready plain text (title, business, billed to, dates, one line per item, the totals as printed, notes, payment terms and details, or on a receipt the day paid and the method) to paste into an email or a chat, and hosts that draw MCP Apps show the page with a Copy button. A paid invoice shows as its receipt, and each payment has its own numbered receipt (the receipt_number invoice_payment_record answers, for example RCT-2026-001), shown by that number or the payment id. Pass id or number (exactly one, from invoice_list, quote_list or invoice_payment_list); kind 'invoice', 'quote' or 'receipt' is optional (else invoice first, then quote, then receipt). It sends nothing and makes no link. Refusals: unknown id or number NOT_FOUND (a removed payment's receipt: reason_code SIMPLER_SALES_RECEIPT_VOID); a missing or doubled id/number or another argument VALIDATION_ERROR; kind 'receipt' before receipts are set up SERVICE_UNAVAILABLE SIMPLER_SALES_RECEIPT_UNMIGRATED; stylesheet unreadable SERVICE_UNAVAILABLE SIMPLER_SALES_DOCUMENT_CHAT_ASSETS_UNAVAILABLE (retry_after); not read within 3 seconds SERVICE_UNAVAILABLE SIMPLER_SALES_DOCUMENT_SHOW_SLOW (call again after retry_after). Read-only tokens and viewers may call it. Free.
输入参数idkindnumber
Prepare what a business sends a client about one issued invoice: purpose 'invoice', 'reminder' (overdue), 'receipt' (paid in full) or 'promise_follow_up' (promised date passed); left out, the one that fits. language 'en', 'ms' or 'zh'; left out, the client's (invoice_client_update message_language), else English. Returns to, subject, body, share_text, a mailto and link_on; share_url only for a member or above with a live link (never made here). NOTHING IS SENT. Refusals (CONFLICT): draft SIMPLER_SALES_MESSAGE_NOT_ISSUED (issue it with invoice_update status 'sent'); cancelled; written off; SIMPLER_SALES_MESSAGE_PURPOSE_UNFIT (send its next_call). Other arguments: VALIDATION_ERROR. Free.
输入参数id必填purposelanguage
Today's collection list, in the business's days (its sales_settings time zone). reminders: each issued invoice still owed that is 3 days before its due date, on it, or 7 or 14 days after, as its client's reminder_cadence allows (standard, from_due, overdue_only or off; set it with invoice_client_update), with the amount owed in CENTS, the step, the language and next_call (the invoice_message_prepare call). A step shows only on its own day. issues: drafts the recurring run made, each with the invoice_update call that issues it; recurring_held: due templates it could not make, and why. NOTHING IS PREPARED OR SENT. Any argument is refused VALIDATION_ERROR (it takes none). Free; changes nothing.
无需输入参数。
A client's statement of account over a period of the business's own days (the sales_settings time zone): the balance they owed before it (opening), each invoice issued, payment received, credit and write-off in it with a running balance, the balance at its end (closing), and what was still owed at its end aged current / 1-30 / 31-60 / 61-90 / over 90 days past due, counted as sales_receivables counts. Only issued invoices count: drafts and cancelled invoices never do. Money is integer CENTS in each invoice's own currency, one section per currency, never converted or added across currencies; read the figures as given. It prepares nothing and sends nothing: returns the figures, document_path (the print-ready page, while signed in) and pdf_next_call (the statement_pdf call that makes the PDF). A statement with more than 150 rows lists its first rows, whole business days only, and lines_cut says which and gives the next_call that lists the rest; the balances, totals and ageing always cover the whole period. When the result has a second content block, it is the statement as copy-ready text (a very long one shortened), and hosts that draw MCP Apps show the statement with a Copy button, as plain text when it is too long to draw as a document. Refusals: a client_id that is not one of your clients is NOT_FOUND (find it with invoice_client_search or invoice_client_list); a date not written YYYY-MM-DD, a to after today, a from after to, or a period longer than 366 days is VALIDATION_ERROR naming the field; a client with more than 2000 issued invoices is PAYLOAD_TOO_LARGE SIMPLER_SALES_STATEMENT_TOO_LARGE (sales_receivables still ages them). Free.
输入参数tofromclient_id必填
Get one issued invoice ready to give the client, in one call: the document, the client link (made if it has none), the PDF (printed or the stored one) and the prepared message (invoice_message_prepare's words, with the link). ready lists the parts made; missing gives each other part's reason_code, reason and next_call. A turned-off link is never re-issued: invoice_share action 'rotate' waits for the owner's approval. NOTHING IS SENT. Refusals (CONFLICT): draft SIMPLER_SALES_MESSAGE_NOT_ISSUED (issue it with invoice_update status 'sent'); cancelled; written off; SIMPLER_SALES_MESSAGE_PURPOSE_UNFIT (send its next_call). Read-only token or viewer: FORBIDDEN. Free.
输入参数id必填purposelanguage
WHAT-IF / scenario lane: runs monthly data YOU supply through a seeded 5,000-path simulation of monthly revenue and costs; bands are simulation outputs, not calibrated probabilities. The paths are clustered into 3-7 outcome bands for the next 6 months, with per-month revenue and cost percentiles and deathRisk, the share of paths the engine marks closed (a distress signal, not a cash-out date). Amounts are in currency (major units, default USD): 1500 or "1500.00" - never cents. currency is one of 16 codes (USD, EUR, GBP, JPY, CNY, AUD, HKD, INR, SGD, MYR, IDR, THB, PHP, VND, BND, MMK); leave it out and USD is assumed, and the output says currency_assumed: true. The engine runs in USD; every output figure converts back into currency at fx_rate_to_usd (USD per 1 unit), named in the top-level currency field. Send cash_balance (the bank balance, negative for an overdraft) with cash_as_of (its date, YYYY-MM-DD, within 45 days) and the cash block adds runway, cash-out share, lowest balance and health from that balance plus each path's revenue minus costs (balance_source 'request'); without them it carries net-flow figures only and its next_step says what to send. Send declared_totals {revenue, costs}, the totals your own source shows for the months sent, and the sums are checked on the server; totals_check echoes them. history_months, shallow (true under 5 months) and blend {yours_pct, peers_pct} (null when shallow) say how much of the result is your own history. Earlier releases removed the per-band cash range and the per-month cash percentiles (they started from an invented balance) and interpreted_money.unit (the top-level currency field replaces it). Refuses with VALIDATION_ERROR and a fix per field: fewer than 2 or more than 120 rows, a date that is not YYYY-MM, revenue or costs sent in cents or as text that is not a number (an exponent such as 1e5, letters other than one currency code or symbol, or a comma that does not group thousands), an amount whose code or symbo
输入参数cash_ondriverscurrencyrecurringcash_as_ofmonthlyData必填cash_balancepaid_historycash_currencyopen_payablesdeclared_totalsopen_receivables
Run the tenant's REAL forecast from the books — cash receipts (recorded invoice payments by payment date, plus paid invoices with no recorded payment at their paid date, flagged) and expenses by expense date, monthly in the tenant's base currency, up to the last complete month (the current month is left out; months are the business's calendar months in its own time zone, set in sales settings, Asia/Singapore when unset, and the books block names it in bucket_timezone) and at most 36 months — through the one import pipeline. The result is STORED, replacing the forecast every member reads, so it is owner or admin only: any other role is refused with FORBIDDEN SIMPLER_FORECAST_IMPORT_ROLE_REFUSED before anything is read, saved, run or charged (ask an owner or admin to run it; forecast.read reads the forecast already stored). No arguments are needed. Optional cash_balance (the bank balance in cash_currency, negative for an overdraft), cash_currency (one of 16 codes) and cash_as_of (its date, YYYY-MM-DD) go together: they are saved as the workspace's declared bank balance, replacing the balance entered before, and then the forecast runs and starts its cash block from that balance. When more than one bank account is saved on the Forecast page, it refuses with CONFLICT SIMPLER_FORECAST_CASH_MULTI_ACCOUNT_REFUSED before anything is saved or run, because one balance would replace them all: ask the owner or an admin to update the balances on the Forecast page, or call without the three cash fields to run from the saved balances. It refuses with SERVICE_UNAVAILABLE SIMPLER_FORECAST_SETTINGS_READ_FAIL when the saved balances cannot be read (retry in a minute). The cash fields refuse like forecast.run's (SIMPLER_FORECAST_CASH_WITHOUT_DATE, SIMPLER_FORECAST_CASH_AS_OF_INVALID, VALIDATION_ERROR naming cash_currency when it is missing or outside the list, or cash_balance when its code or symbol names another currency than cash_currency, before anything is saved) and with SERVICE_UN
输入参数cash_as_ofcash_balancecash_currency
Read the tenant's STORED forecast — the verify-read for this rail. view picks the answer, one of summary, monthly, variance, scenarios, weekly (default summary). summary: the outcome bands (label, growth_direction, probability_pct, final_month_revenue_low and _high, distress_risk_pct, path_count), the cash block, blend {yours_pct, peers_pct} (the share of the result from this business's own history versus businesses like it; null when shallow). monthly: per month revenue, costs and net at p10, p25, p50, p75 and p90 with distress_risk_pct, plus balance_p10 to balance_p90 and below_zero_cum_pct when a balance anchors the cash block, and the cash block. This release moved monthlyForecast out of the default answer into view 'monthly'. Every view carries view, dataMonths, history_months, shallow (true under 5 months of history) and CFO narration status, money formatted in the business's currency, named in the top-level currency field: the engine runs in USD and figures convert back at the rate pinned on the stored result (fx_rate_to_usd); before this release they were USD. Free. Refuses with VALIDATION_ERROR naming view when it is not in the list. The cash block is computed from a real bank balance plus each simulated path's revenue minus costs: with basis 'anchored' it carries provenance (the balance grade), balance_source ('statement': the latest balance on bank statements imported with banking.import_statement, used while under 31 days old in place of a typed balance for the same account; a typed account whose label ends in other last 4 digits, or the same digits in another currency, and dated on or after the statement, is added to it and provenance is then declared (an older one is left out: save it again with today's date); 'settings': entered on the Forecast page or saved by forecast.run_stored; 'upload_row': the cash row of an uploaded sheet), balance_as_of, runway_months_p10 and _p50 (null = no cash-out within the horizon), cash_out_pct, lowest_balance_p10, burn_
输入参数viewcash_ondriversrecurringpaid_historyopen_payablesopen_receivables
[paid: $0.042/image max] Generate 1-3 images from a text prompt on the first lane that delivers, tried in order: gemini-2.5-flash-image via the Cloudflare AI Gateway, square requests only ($0.0406/image), then @cf/black-forest-labs/flux-2-dev via Cloudflare Workers AI ($0.00/image), then google/nano-banana-2-lite via fal ($0.042/image). Each lane settles its own price per delivered image, so an image never costs more than the fal price, the credit a call must have available before it runs; price.charged_micro_usd in the result is the actual charge. Each image is stored in this workspace's image library and returned as JSON {images:[{url, asset_key, download_url?, width, height}], price, next} plus a preview; never a provider link. A result with no download_url says why in download_url_unavailable. Refuses: VALIDATION_ERROR on an empty prompt (describe the image), INSUFFICIENT_CREDITS (add credits), SIMPLER_IMAGE_PROMPT_REFUSED names the label (sexual, minor, real_person or other_unsafe): rewrite the prompt without it, for example no real person's name or likeness; SIMPLER_IMAGE_PROMPT_CHECK_UNAVAILABLE (the safety check is down, nothing charged: retry later); SIMPLER_IMAGE_OUTPUT_FLAGGED (the output failed the content check and was refunded: change the prompt); SIMPLER_IMAGE_OUTPUT_SCAN_UNAVAILABLE (outputs cannot be checked right now, nothing charged: retry later). A partial result lists refunded outputs in output.withheld; SIMPLER_IMAGE_RESULT_UNDELIVERED means nothing was charged: retry. For canvas-sized generation inside an edit session use image.generate_for_edit. NEXT: pass images[0].asset_key as image_asset_key to image.variation or image.upscale.
输入参数countwidthheightprompt必填request_refpreview_format
spreadsheet.create_with_content
Create a spreadsheet in the user's library from CSV content in ONE call: the platform stores the bytes (honest text/csv) and registers the file row. Free — storage costs nothing; only AI lanes bill. Returns the file row including its id. Refuses: VALIDATION_ERROR when title or csv_content is empty (send both), VALIDATION_ERROR when csv_content is over 10 MB (split it into smaller files), NOT_FOUND when folder_id names no folder in this workspace (call spreadsheet_folder_list, or leave folder_id out), FORBIDDEN when your role is viewer or your token is read-only (ask the owner for the member role, or connect with the 'mcp' scope). Nothing is stored when it refuses. NEXT: spreadsheet_file_list to see the library.
输入参数title必填folder_idcsv_content必填
Confirm receipt of a note in your cross-tenant agent_note inbox — the ONLY edit a recipient holds, moving status unread to read under the registry's transition guard. Idempotent: re-confirming an already-read note is a no-op, and the subject/body stay fixed forever so a recipient can never rewrite what the sender said. NEXT: agent_note_list to see the rest of the inbox.
输入参数id必填bodystatussubjectfrom_tenant_idconsent_grant_idrelated_entity_idrelated_entity_type
List your agent_note rows (newest first).
输入参数limitcursor
Read one agent_note by id.
输入参数id必填
Read one brand_assets by id.
输入参数id必填
List your brand_assets rows (newest first).
输入参数limitcursor
List your consent_grant rows (newest first).
输入参数limitcursor
Read one consent_grant by id.
输入参数id必填
Create a contact and, in the same call, log its first note and/or first interaction — the composite first-touch door. Children validate before the contact write; if the contact commits but a child then fails, the error names the contact's id plus the exact call to finish it, never a silent orphan. A contact with the same email or phone already in this tenant refuses with CONFLICT. NEXT: contact_upsert merges into an existing contact instead of creating a duplicate.
输入参数namenotetagsemailnotesphonesourcestatusaddresscompanyinteractionlast_contact_at另有 1 个
Update a contact you own (optionally compare-and-set via expected_updated_at).
输入参数id必填nametagsemailphonesourcestatusaddresscompanylast_contact_atexpected_updated_at
Delete a contact you own.
输入参数id必填
Read one contact by id.
输入参数id必填
List your contact rows (newest first).
输入参数limitcursor
Search your contact rows by text.
输入参数q必填limitcursor
Add a note to a contact — the same door as the granular tool, extended only to accept contact_name, contact_email or contact_phone in place of contact_id. A name match must be unique: more than one hit refuses, listing the candidate ids; zero matches on every alias refuses with the runnable two-step call to create the contact first, then retry. NEXT: contact_upsert when no contact exists yet.
输入参数contentcontact_idcontact_namecontact_emailcontact_phone
List your contact_note rows (newest first).
输入参数limitcursor
Read one contact_note by id.
输入参数id必填
Delete a contact_note you own.
输入参数id必填
Pins one widget or a saved artifact onto the operator's home canvas. kind='widget' requires widget_key from the shipped enum; kind='artifact' requires content_ref (an assistant artifact id) — the door enforces whichever pair the kind demands, since the schema alone cannot express it. Rows are private to the creating user, even though teammates share the same tenant. NEXT: desk_surface_list reads the current layout.
输入参数hwxykindz_indexwidget_keycontent_ref
Moves, resizes, or restacks a surface already on the desk canvas — x/y/w/h/z_index are real column writes, not a layout cache. The surface's identity is frozen here: kind, widget_key, and content_ref never change through this door, only via delete then re-create. NEXT: desk_surface_list to find the id to move.
输入参数hwxyid必填kindz_indexwidget_keycontent_refexpected_updated_at
Read one desk_surface by id.
输入参数id必填
List your desk_surface rows (newest first).
输入参数limitcursor
Delete a desk_surface you own.
输入参数id必填
Create a canvas project from a Fabric.js toJSON serialization (canvas_json, required): every embedded data:image src is pulled out, hashed, and written to a tenant-scoped, content-addressed R2 key before the row is saved, so canvas_json never carries image bytes and identical images dedupe across projects. SVG, an unrecognized image type, an oversized embedded image, or a canvas still too large after externalization refuse the whole create — nothing is silently dropped. An optional thumbnail_data_url is externalized the same way into thumbnail_key; thumbnail_key and version are server-set and refuse if you pass them. NEXT: edit_project_update to autosave the same project as it changes.
输入参数namewidthheightversioncanvas_jsonthumbnail_keythumbnail_data_url
Save changes to an existing canvas project by id — the autosave door: send only the fields that changed (name, canvas_json, width, height, thumbnail_data_url), everything else on the row is left alone. A canvas_json you send goes through the same image-externalization and hygiene refusal as edit_project_create (embedded images become R2 keys; SVG, unrecognized types, oversized images, or a still-too-large canvas refuse the whole save). version is bumped by the door itself on every save and thumbnail_key is server-minted from thumbnail_data_url — both refuse if you pass them directly. NEXT: edit_project_read to confirm the saved version.
输入参数id必填namewidthheightversioncanvas_jsonthumbnail_keythumbnail_data_urlexpected_updated_at
Read one edit_project by id.
输入参数id必填
List your edit_project rows (newest first).
输入参数limitcursor
Delete a edit_project you own.
输入参数id必填
Edits an expense's own fields only — status and approval stamps refuse with VALIDATION_ERROR here since those are transitions (expense_submit, expense_approve, expense_reject, expense_reimburse). amount_cents, if changed, must stay integer CENTS. Only the expense's own creator may edit it, and content freezes once the row is 'pending', reimbursed, or approved by someone else — draft, rejected, and your own self-approved rows stay editable.
输入参数id必填notesstatusvendorcurrencyocr_jsontax_typetags_jsonapproved_atapproved_bycategory_idreceipt_key另有 11 个
Deletes an expense you created — draft and rejected rows only. Pending, approved, and reimbursed rows are approval-trail records and refuse with CONFLICT (approval_locked: true), and the lock is pinned into the delete itself so a status change racing your read still refuses instead of silently deleting. NEXT: expense_reject it first (admin+) if it must leave the books.
输入参数id必填notesstatusvendorcurrencyocr_jsontax_typetags_jsonapproved_atapproved_bycategory_idreceipt_key另有 10 个
Rejects a submitted expense claim — requires the admin or owner role, and only a 'pending' expense qualifies (CONFLICT otherwise). rejection_reason (up to 500 chars) is optional but records why; rejected is terminal and never counts as spend, so a corrected claim is a fresh expense_create, never a resubmit.
输入参数id必填notesstatusvendorcurrencyocr_jsontax_typetags_jsonapproved_atapproved_bycategory_idreceipt_key另有 10 个
Marks an approved expense as paid out — restricted to the tenant owner because it moves real money, and only an 'approved' expense qualifies (CONFLICT otherwise). Stamps reimbursed_at, after which the row's content freezes unconditionally since the amount approved is the amount recorded as paid. Records the payout only — no funds move automatically.
输入参数id必填notesstatusvendorcurrencyocr_jsontax_typetags_jsonapproved_atapproved_bycategory_idreceipt_key另有 10 个
Read one expense by id.
输入参数id必填
List your expense rows (newest first).
输入参数limitcursor
Search your expense rows by text.
输入参数q必填limitcursor
Aggregate (count/sum) over your expense rows.
输入参数function必填property
Create a expense_budget.
输入参数currencyis_activecategory_idalert_at_pctmonthly_limit_cents必填
Update a expense_budget you own (optionally compare-and-set via expected_updated_at).
输入参数id必填currencyis_activecategory_idalert_at_pctexpected_updated_atmonthly_limit_cents
Delete a expense_budget you own.
输入参数id必填
Read one expense_budget by id.
输入参数id必填
List your expense_budget rows (newest first).
输入参数limitcursor
Adds a custom category to your tenant's category table — slug must be 1-50 chars of lowercase a-z, 0-9, '-' or '_' and unique per tenant (CONFLICT if taken). is_default is server-owned: supplying it at all refuses with VALIDATION_ERROR, and this door always creates with is_default 0 — the 9 seeded defaults exist only via expense_category_ensure_defaults. sort_order defaults to the next open slot when omitted.
输入参数iconnameslugcoloris_defaultsort_order
Edits a category's name, icon, color, or sort_order — slug and is_default are the category's fixed identity, and any attempt to change either refuses with VALIDATION_ERROR. color, when given, must be a #rrggbb hex value. Create a new category instead of trying to rename an existing slug.
输入参数id必填iconnameslugcoloris_defaultsort_orderexpected_updated_at
Deletes a custom category — categories are tenant-shared, so any tenant member can remove one regardless of who created it; the 9 seeded defaults are undeletable and refuse with CONFLICT (default_category: true). Expenses already carrying the deleted category keep their category_id untouched and simply render as Uncategorized; nothing is reassigned or blocked.
输入参数id必填iconnameslugcoloris_defaultsort_order
expense_category_ensure_defaults
Seeds the 9 canonical default categories (Food & Dining, Transport, Utilities, Shopping, Entertainment, Healthcare, Travel, Office & Supplies, Other) into your tenant, skipping any slug that already exists. Takes no arguments and is safe to call repeatedly or concurrently — it converges rather than duplicating. NEXT: expense_category_list to see the result.
输入参数iconnameslugcoloris_defaultsort_order
Read one expense_category by id.
输入参数id必填
List your expense_category rows (newest first).
输入参数limitcursor
expense_recurrence_create
Create a expense_recurrence.
输入参数notesvendor必填currencynext_due必填frequency必填is_activecategory_idday_of_weekamount_cents必填day_of_monthtotal_generatedlast_generated_at
expense_recurrence_update
Update a expense_recurrence you own (optionally compare-and-set via expected_updated_at).
输入参数id必填notesvendorcurrencynext_duefrequencyis_activecategory_idday_of_weekamount_centsday_of_monthtotal_generated另有 2 个
expense_recurrence_delete
Delete a expense_recurrence you own.
输入参数id必填
Read one expense_recurrence by id.
输入参数id必填
List your expense_recurrence rows (newest first).
输入参数limitcursor
Create-or-update a interaction keyed on source_ref.
输入参数summary必填contact_id必填source_ref必填occurred_atinteraction_type必填
List your interaction rows (newest first).
输入参数limitcursor
Read one interaction by id.
输入参数id必填
Edits an invoice's header fields and status. status 'paid' cannot be set here — it derives from the payment ledger, so call invoice_payment_record instead. Status moves are machine-checked (draft to sent/cancelled, sent to cancelled); cancelled is terminal and a paid invoice never reopens by hand. A move to 'sent' stamps sent_at automatically when omitted, and currency is ledger-locked once any live payment exists. An agent's change to notes or payment_terms on an issued invoice waits for the owner's approval; on a draft it does not. tax_scheme and prices_include_tax are fixed at creation, as is the tax rate. NEXT: invoice_payment_record to settle money, invoice_read to verify.
输入参数id必填notesstatuspaid_atsent_atcurrencydue_datecash_saleclient_idsource_idissue_datetax_scheme另有 10 个
Returns share_url, the client's view link for this invoice, and the full document (parties, lines, totals in integer CENTS) in one call. action: 'get' (default) returns the live link; 'rotate' replaces it and the old link stops working; 'revoke' turns it off. A link the owner turned off stays off for agents: 'get' never re-issues it, and an agent's 'rotate' waits for the owner's approval. Anyone with the link can open the page until the invoice is cancelled or 90 days after payment (see link_serving). There is no PDF file yet; the link opens a print-ready page the client can print or save as PDF. Nothing is sent: give the link to the owner, who decides whether it goes to the client.
输入参数id必填actioninvoice_idfresh_after
invoice_payer_confirmation
Acts on a payer's report, sent from the invoice's client page, that they have paid. action 'accept' records the payment with the same writer as invoice_payment_record, graded counterparty_confirmed: the amount is amount_cents (or amount) when given, else the balance still owed; occurred_at defaults to when the payer reported. An agent's accept waits for the owner's approval. action 'dismiss' closes a report whose money did not arrive. Find reports in invoice_read's payer_confirmations. Refuses a report already accepted or dismissed with CONFLICT (invoice_read shows it), and an invoice with nothing owed unless amount_cents comes with allow_overpayment. Nothing is sent to the payer.
输入参数idnoteforceaction必填amountmethodinvoice_idoccurred_atamount_centsallow_overpayment
[REQUIRES APPROVAL] Issues a numbered debit note that raises what an issued ('sent' or 'paid') invoice is owed: an extra charge, or a price or tax correction. It is numbered from the debit note series and adds amount_cents (or a decimal STRING amount), tax at the invoice's rate inside, in its currency; a 'paid' invoice goes back to 'sent' until the rest is paid. Refuses a draft (change its lines instead), a cancelled invoice, an invoice with no lines, another currency, and a paid invoice with no payment recorded (record it first with invoice_payment_record); every refusal names the call to send. Never deleted: undo one with a credit_note. An agent's call parks for approval. Nothing is sent. NEXT: invoice_read.
输入参数amountreasoncurrencydebit_kindinvoice_idoccurred_atamount_centsinvoice_number
Voids a 'sent' invoice with no money on it and reissues it under the next number: 'sent', dated today, same client, currency, notes, terms and lines, tax on today's rules, the old days to pay unless due_date is sent. A foreign-currency sg_gst invoice issued before today needs fx_rate_to_sgd and fx_rate_date for today unless its rate is dated today. The old one is cancelled, its client link stops working, both trails link them. Paid, part-paid, credited or written-off invoices refuse: correct them with a credit note (invoice_adjustment_record). When present, the second content block is the new invoice as copy-ready text. Nothing is sent. NEXT: invoice_share only if the user asks for a link.
输入参数idreasondue_datefx_rate_datefx_rate_to_sgdinvoice_numberfx_rate_to_sgd_ppmexpected_updated_at
Records the date a client promised to pay an issued invoice that still has money owed: promised_payment_date 'YYYY-MM-DD', the business's own date, today or later. clear true removes it. invoice_read then shows promise_status: pending until that business day ends, kept when paid in full by then, broken after it. A broken promise makes promise_follow_up the default purpose of invoice_message_prepare. Each change is kept in the invoice's activity as promise_set. Refuses a draft, a cancelled invoice and one with nothing owed (CONFLICT), and a past or malformed date (VALIDATION_ERROR). Nothing is sent. NEXT: invoice_read.
输入参数idnoteclearinvoice_numberexpected_updated_atpromised_payment_date
Returns one invoice with its money and state worked out on read, in integer CENTS: subtotal_cents, tax_cents, total_cents, paid_cents, credited_cents, adjusted_cents, remaining_cents (copy remaining_cents, never compute it). state: draft, sent, partially_paid, overdue, written_off, paid or cancelled. Overdue means issued, still owed and due before today in the business time zone (sales_settings.timezone, unset = Asia/Singapore); days_overdue counts days there. activity lists the newest 50 events; viewed_count and last_viewed_at count every view. payer_confirmations lists the payer's "I've paid" reports. An unknown id refuses with NOT_FOUND: find it with invoice_list or invoice_search.
输入参数id必填
Lists your invoices, newest first (200 at most; pass limit and cursor to page). Every row carries the same worked-out money and state as invoice_read: total_cents, remaining_cents, state, is_overdue, days_overdue (integer CENTS, business days). To find what to chase, pass state 'overdue': only invoices issued, still owed and due before today in the business time zone come back. payer_confirmations_pending counts the payer's "I've paid" reports waiting on each row. Refuses an unlisted state, a limit outside 1-200 or a malformed cursor with VALIDATION_ERROR: resend with a listed state, without limit, or with next_cursor exactly as returned.
输入参数limitstatecursor
Finds invoices whose text fields (invoice number, notes, payment terms) contain every word of q. Rows carry the same worked-out money and state as invoice_read: total_cents, remaining_cents, state, is_overdue (integer CENTS), and payer_confirmations_pending. Refuses an empty q with VALIDATION_ERROR: send the invoice number, such as INV-2026-0001, or a word from its notes.
输入参数q必填limitcursor
Read one invoice_adjustment by id.
输入参数id必填
List your invoice_adjustment rows (newest first).
输入参数limitcursor
invoice_adjustment_delete
[REQUIRES APPROVAL] Retires a dilution fact row — the only correction lane (adjustments are append-only; amounts are never edited). If the retired row was a credit that settled the invoice, the status rolls from 'paid' back to 'sent' and paid_at clears; the remaining balance and the derived 'written_off' state re-derive from the live rows immediately. An agent's call parks here for human approval. NEXT: invoice_adjustment_record to re-record the correct amount.
输入参数id必填reasoncurrencyinvoice_idoccurred_atreason_codeamount_centsadjustment_idcredit_outcomeadjustment_type
Create a invoice_client.
输入参数name必填emailnotesphoneaddresscompanycontact_idmessage_languagereminder_cadence
Create-or-update a invoice_client keyed on email.
输入参数name必填email必填notesphoneaddresscompanycontact_idmessage_languagereminder_cadence
Update a invoice_client you own (optionally compare-and-set via expected_updated_at).
输入参数id必填nameemailnotesphoneaddresscompanycontact_idmessage_languagereminder_cadenceexpected_updated_at
Delete a invoice_client you own.
输入参数id必填
Read one invoice_client by id.
输入参数id必填
List your invoice_client rows (newest first).
输入参数limitcursor
Search your invoice_client rows by text.
输入参数q必填limitcursor
invoice_client_link_tenant
[REQUIRES APPROVAL] Asserts that a billing client IS an on-platform tenant (or pass counterparty_tenant_id null to unlink) and retro-stamps that client's existing invoices with the link in the same call — invoices_stamped in the result is the count. Linking requires the counterparty's 'cross_tenant_settlement' consent AND a live network relationship (an active match or a deal thread); unlinking passes neither gate, since it withdraws your own assertion rather than making a new one. NEXT: invoice_client_read to read back what linked.
输入参数id必填nameemailnotesphoneaddresscompanyclient_idcontact_idmessage_languagereminder_cadencecounterparty_tenant_id必填
Adds one line item to an invoice. unit_price_cents is integer CENTS, 0 or more ($15.00 → 1500); quantity is 0.001 to 1,000,000 with up to 3 decimals (1.5 hours → 1.5); unit is an optional label (hr, kg); discount_bps is an optional line discount (10% → 1000). quantity × unit_price_cents is at most 10,000,000,000. Refuses a negative price (send discount_bps instead), a 'paid' parent (retire the payment first) and a 'cancelled' parent (issue a new invoice). Re-derives the invoice's paid/sent status. tax_code is the line's code under the document's tax_scheme, refused on a document without a scheme. NEXT: invoice_read to see the updated total.
输入参数unitpositionquantitytax_codeinvoice_iddescriptiondiscount_bpsunit_price_cents
Edits a line item's description, quantity, unit, price or discount, or re-parents it to another invoice. expected_updated_at is required: the line's updated_at from your read; without it nothing is written and the refusal names the current value; a line changed since then answers CONFLICT. Bounds: unit_price_cents is integer CENTS, 0 or more; quantity 0.001 to 1,000,000 (3 decimals); discount_bps 0 to 10000; quantity × unit_price_cents at most 10,000,000,000. unit "" clears the unit. Refuses when the current or target invoice is paid or cancelled. tax_code is the line's code under the document's tax_scheme, refused on a document without a scheme. NEXT: invoice_read to see the updated total.
输入参数id必填unitpositionquantitytax_codeinvoice_iddescriptiondiscount_bpsunit_price_centsexpected_updated_at必填
Soft-deletes a line item — it leaves the invoice and its derived total immediately, but the row is retired for audit history, never removed. expected_updated_at is required: the line's updated_at from your read (invoice_item_read); without it the removal is refused and the refusal names the current value. Refuses when the parent invoice is 'paid' (ledger-locked: retire the payment first) or 'cancelled' (terminal: its lines stay as issued), and with CONFLICT when the line changed since that read (read it again). If retiring the line settles the remaining balance on a partially-paid invoice, the parent re-derives to 'paid' by itself. NEXT: invoice_read to see the updated total.
输入参数id必填unitpositionquantitytax_codeinvoice_iddescriptiondiscount_bpsunit_price_centsexpected_updated_at必填
Read one invoice_item by id.
输入参数id必填
List your invoice_item rows (newest first).
输入参数limitcursor
Read one invoice_payment by id.
输入参数id必填
List your invoice_payment rows (newest first).
输入参数limitcursor
[REQUIRES APPROVAL] Retires a payment fact row — the only correction lane (payments are append-only; amounts are never edited). If retiring it un-settles the invoice, the reversal itself rolls the status from 'paid' back to 'sent' and clears paid_at. An agent's call parks here for a human to approve in the Simpler UI; a human's call is its own approval. NEXT: invoice_payment_record to re-record the correct amount.
输入参数id必填notemethodcurrencyinvoice_idpayment_idoccurred_atamount_cents
Create a invoice_recurring.
输入参数notestitle必填ends_oncurrencynext_due必填client_idfrequency必填is_activeitems_json必填tax_schemeday_of_weekday_of_month另有 4 个
Update a invoice_recurring you own (optionally compare-and-set via expected_updated_at).
输入参数id必填notestitleends_oncurrencynext_dueclient_idfrequencyis_activeitems_jsontax_schemeday_of_week另有 6 个
Delete a invoice_recurring you own.
输入参数id必填
Read one invoice_recurring by id.
输入参数id必填
List your invoice_recurring rows (newest first).
输入参数limitcursor
Skips a recurring template's next invoice: next_due moves one period on (the template's own weekly, monthly or yearly day) and no invoice is made. A skip does not count toward max_invoices. Refuses NOT_FOUND for an id outside your tenant (call invoice_recurring_list) and CONFLICT when the template has ended (raise ends_on or max_invoices with invoice_recurring_update) or changed since expected_updated_at (read it again). Each call skips one run: to skip the run after, send expected_updated_at from this answer. Nothing is sent. NEXT: invoice_recurring_read.
输入参数id必填expected_updated_at
Post to one of the tenant's 8 market-signal wish-bar slots — a buy, sell, swap, capacity-offer or capacity-request visible ONLY to platform-matched partners, never the wider network. The door counts your OPEN signals server-side before writing: the 9th is refused with slots_used/slots_max in the error rather than silently queued. NEXT: market_signal_update to close or fulfil a signal and free a slot.
输入参数notesstatusproductcurrencydeadlinelocationquantityprice_centssignal_type
Update a market_signal you own (optionally compare-and-set via expected_updated_at).
输入参数id必填notesstatusproductcurrencydeadlinelocationquantityprice_centssignal_typeexpected_updated_at
List your market_signal rows (newest first).
输入参数limitcursor
Read one market_signal by id.
输入参数id必填
Register a buyer in the LHDN buyer registry so it attaches to future e-invoices with one pick (customer_id) instead of typing the party every time. Validates the TIN format, and validates state_code against the LHDN state table when you send one — a buyer with no real TIN uses the LHDN generic TIN (EI00000000010 Malaysian public, EI00000000020 foreign) instead. NEXT: myinvois_invoice_generate with customer_id.
输入参数brntincitynameemailnotesaddresssst_numberstate_codepostal_codecountry_codecontact_number
Edit a registered buyer's LHDN details — send only the fields you are changing. When tin is included it is re-checked against the same format gate create runs, and when state_code is included it is re-checked against the LHDN state table, so an edited buyer stays valid to generate against. Never touches e-invoices already generated for this buyer; each one sealed its own copy of the buyer party. NEXT: myinvois_customer_list to find the id.
输入参数id必填brntincitynameemailnotesaddresssst_numberstate_codepostal_codecountry_code另有 2 个
Delete a registered buyer. E-invoices already generated for this buyer keep their sealed copy of the buyer party and are never touched. Refuses an id outside your tenant with NOT_FOUND: call myinvois_customer_list for valid ids.
输入参数id必填
Read one registered buyer by id: name, TIN, BRN, SST number, address and contact. myinvois_invoice_generate seals the name, TIN, BRN, address and contact; the buyer's SST number stays on this record and is not sealed on the e-invoice. Refuses an id outside your tenant with NOT_FOUND: call myinvois_customer_list or myinvois_customer_search for valid ids. NEXT: myinvois_invoice_generate with this id as customer_id.
输入参数id必填
List registered buyers, newest first, to pick a customer_id for myinvois_invoice_generate. An empty list means none are registered yet: call myinvois_customer_create, or send an inline buyer {name, tin} to myinvois_invoice_generate instead.
输入参数limitcursor
Find registered buyers by text: every word must match one of the buyer's text fields, such as name, TIN, BRN, email or address. Refuses an empty q with VALIDATION_ERROR. No match returns an empty list: call myinvois_customer_create to register the buyer. NEXT: myinvois_invoice_generate with the id as customer_id.
输入参数q必填limitcursor
List your myinvois_invoice rows (newest first).
输入参数limitcursor
Find generated e-invoices by text: every word must match one of the document's text fields, such as invoice number, buyer name or buyer TIN. Refuses an empty q with VALIDATION_ERROR. Rows carry no field sheet: call myinvois_invoice_read with the id for portal_field_sheet. No match returns an empty list: call myinvois_invoice_list to browse the newest.
输入参数q必填limitcursor
[REQUIRES APPROVAL] Save the one-time LHDN supplier profile — the door checks for an existing row on your tenant and creates or updates in place, so this is the only write you ever call. Validates the TIN format, checks msic_code is a 5-digit MSIC code, and checks state_code against the LHDN state table before the row moves. NEXT: myinvois_invoice_generate reads this profile as the supplier party of every e-invoice.
输入参数brntincityemailscopemsic_codesst_numberstate_codepostal_codecompany_namecountry_codeaddress_line1另有 7 个
Read the supplier profile by id: the party printed on every e-invoice (company, TIN, BRN, SST and tourism tax numbers, MSIC code, address). Refuses an id outside your tenant with NOT_FOUND: call myinvois_settings_list, which returns the one profile row. NEXT: myinvois_settings_save to change it.
输入参数id必填
List the supplier profile: at most one row per tenant. An empty list means setup is not done, and myinvois_invoice_generate refuses until it is: call myinvois_settings_save with the company, TIN, BRN, MSIC code and address. NEXT: myinvois_invoice_generate.
输入参数limitcursor
Save a reusable line-item preset so a repeat invoice's items do not get re-typed. line_items_json is parsed and each item validated by the SAME checker myinvois_invoice_generate uses (description, quantity, unit_price_cents in integer CENTS, tax_rate_bps in basis points, tax_type/classification_code/unit_code against the LHDN code tables) and re-serialized canonically, so a saved template's items are always generate-ready. NEXT: myinvois_template_list to pull the items back out for a generate call.
输入参数namenotesdescriptionpayment_termsline_items_json
Edit a saved line-item preset. When line_items_json is included it is re-parsed and every item re-validated exactly as create does, so an edited template cannot drift into a shape myinvois_invoice_generate would reject. NEXT: myinvois_template_list to find the id.
输入参数id必填namenotesdescriptionpayment_termsline_items_jsonexpected_updated_at
Delete a saved line-item preset. E-invoices generated from it are never touched: each one sealed its own lines. Refuses an id outside your tenant with NOT_FOUND: call myinvois_template_list for valid ids.
输入参数id必填
Read one line-item preset by id. Its line_items_json holds generate-ready items: pass them as line_items to myinvois_invoice_generate. Refuses an id outside your tenant with NOT_FOUND: call myinvois_template_list for valid ids.
输入参数id必填
List saved line-item presets, newest first. Each line_items_json is generate-ready: pass its items as line_items to myinvois_invoice_generate. An empty list means none are saved yet: call myinvois_template_create.
输入参数limitcursor
Edits a quote's header fields and bookkeeping status (draft, sent, accepted, declined move freely). status 'converted' and converted_invoice_id are convert-flow-owned — hand-setting either refuses, and a converted quote is frozen: no status move and no header edit (it could convert again and double-bill; its invoice is the live document, so edit that). tax_scheme and prices_include_tax are fixed at creation, as is the tax rate. NEXT: quote_convert to create the invoice and record the link atomically.
输入参数id必填notesstatuscurrencyclient_idissue_datetax_schemevalid_untilquote_numbertax_rate_bpsprices_include_taxexpected_updated_at另有 1 个
Returns share_url, the client's view link for this quote, and the full document (parties, lines, totals in integer CENTS) in one call. action: 'get' (default) returns the live link; 'rotate' replaces it and the old link stops working; 'revoke' turns it off. A link the owner turned off stays off for agents: 'get' never re-issues it, and an agent's 'rotate' waits for the owner's approval. Anyone with the link can open the page until the quote expires, is declined or converted (see link_serving). There is no PDF file yet; the link opens a print-ready page the client can print or save as PDF. Nothing is sent: give the link to the owner, who decides whether it goes to the client.
输入参数id必填actionquote_idfresh_after
Returns one quote with subtotal_cents, tax_cents and total_cents worked out from its live lines (integer CENTS) and effective_status, which reads 'expired' once a sent quote's valid_until has passed (the stored status never says so). A quote with a tax_scheme also returns tax_summary (each line's tax code, net, tax and gross, and the per-code totals). Refuses an unknown id with NOT_FOUND: find the id with quote_list or quote_search.
输入参数id必填
Lists your quotes, newest first (200 at most; pass limit and cursor to page). Every row carries total_cents (integer CENTS) and effective_status, so an expired quote reads 'expired'. Refuses a limit outside 1-200 or a malformed cursor with VALIDATION_ERROR: resend without them, or with next_cursor exactly as returned.
输入参数limitcursor
Finds quotes whose text fields (quote number, notes) contain every word of q; rows carry total_cents (integer CENTS) and effective_status. Refuses an empty q with VALIDATION_ERROR: send the quote number, such as QUO-2026-0001, or a word from its notes.
输入参数q必填limitcursor
Adds one line item to a quote. unit_price_cents is integer CENTS, 0 or more ($15.00 → 1500); quantity is 0.001 to 1,000,000 with up to 3 decimals (1.5 hours → 1.5); unit is an optional label (hr, kg); discount_bps is an optional line discount (10% → 1000). quantity × unit_price_cents is at most 10,000,000,000. Refuses a negative price (send discount_bps instead), a line above the ceiling (split it) and any line on a converted quote (CONFLICT: change its invoice instead). tax_code is the line's code under the document's tax_scheme, refused on a document without a scheme. NEXT: quote_read to see the quote.
输入参数unitpositionquantityquote_idtax_codedescriptiondiscount_bpsunit_price_cents
Edits a quote line's description, quantity, unit, price or discount, or moves it to another quote. expected_updated_at is required: the line's updated_at from your read; without it nothing is written and the refusal names the current value; a line changed since then answers CONFLICT. Refuses a line of a converted quote or a move onto one (CONFLICT: change its invoice instead). Bounds: unit_price_cents is integer CENTS, 0 or more; quantity 0.001 to 1,000,000 (3 decimals); discount_bps 0 to 10000; quantity × unit_price_cents at most 10,000,000,000. unit "" clears the unit. tax_code is the line's code under the document's tax_scheme, refused on a document without a scheme. NEXT: quote_read.
输入参数id必填unitpositionquantityquote_idtax_codedescriptiondiscount_bpsunit_price_centsexpected_updated_at必填
Soft-deletes a quote line — it leaves the quote and its totals immediately, but the row is retired for audit history, never removed. expected_updated_at is required: the line's updated_at from your read (quote_item_read); without it the removal is refused and the refusal names the current value. Refuses with CONFLICT when the line changed since that read (read it again and decide on the current line) and on a converted quote (its lines are frozen: change its invoice instead). NEXT: quote_read to see the quote.
输入参数id必填unitpositionquantityquote_idtax_codedescriptiondiscount_bpsunit_price_centsexpected_updated_at必填
Read one quote_item by id.
输入参数id必填
List your quote_item rows (newest first).
输入参数limitcursor
[REQUIRES APPROVAL] Saves your business identity and document defaults (one row per business; scope is 'default'). timezone is the business clock: an invoice turns overdue at midnight in that zone after its due day, and days_overdue counts days there; unset means Asia/Singapore. Left out, timezone and the text fields keep their saved value, but defaulted fields (default_currency, default_tax_rate_bps, payment_terms_days, invoice_prefix, quote_prefix, template_style) reset, so resend them from sales_settings_read. An agent call waits for the owner's approval. Refuses an unlisted timezone or currency, or a tax rate outside 0-10000, with VALIDATION_ERROR before it waits for approval: send a listed value.
输入参数scope必填tax_idtimezonebank_nametax_schemebank_accountquote_prefixbusiness_namebusiness_emailbusiness_phoneinvoice_prefixtemplate_style另有 7 个
sales_settings_numbering_set
[REQUIRES APPROVAL] Sets where a document type's numbers continue, for example after moving from another invoicing tool. doc_type: invoice, quote, credit_note, debit_note or receipt. next_number is the sequence number the next document gets (42 prints as INV-2026-042). Numbering only moves forward: a number at or below the last one used or skipped is refused with VALIDATION_ERROR naming that number, and nothing changes. prefix sets the credit_note, debit_note or receipt prefix; invoice and quote prefixes are invoice_prefix and quote_prefix on sales_settings_upsert. An agent call waits for the owner's approval. Read the current numbers with sales_settings_numbering_read.
输入参数prefixdoc_type必填next_number
List your sales_settings rows (newest first).
输入参数limitcursor
Read one sales_settings by id.
输入参数id必填
settlement_proposal_accept
Accept a settlement obligation recorded against your tenant as payee — moves status proposed to accepted and stamps accepted_at under the registry's transition guard. Calling it again on an already-accepted row is idempotent (accepted_at simply re-stamps); once a proposal reaches settled the guard refuses any further move, since settled is terminal. Recording agreement only: no money moves here, settlement execution is a later rail's door. NEXT: settlement_proposal_read to verify the accepted row.
输入参数id必填statuscurrencyaccepted_atdescriptionamount_centspayer_tenant_idconsent_grant_idrelated_entity_idrelated_entity_type
List your settlement_proposal rows (newest first).
输入参数limitcursor
Read one settlement_proposal by id.
输入参数id必填
Register a spreadsheet file row in the library for bytes that already sit in R2: r2_key must be a spreadsheets/<your tenant>/ key minted by the upload route or spreadsheet.create_with_content — a caller-invented, foreign-tenant, or wrong-domain key is refused. sheet_count, row_count, and column_count are unverified client-reported hints, since nothing server-side parses the binary. NEXT: spreadsheet.create_with_content stores the bytes and registers the row together.
输入参数tagstitler2_keysourceai_promptfile_sizefolder_idrow_countdeleted_atsheet_countsheet_namescolumn_count另有 3 个
Edit a spreadsheet file's metadata — title, tags, folder_id, or the AI-analysis fields — without touching the underlying R2 object. r2_key and source are birth facts: including either field in the call at all, even set to its current value, is refused — re-upload as a new file to change custody or provenance. Moving folder_id re-verifies the target folder belongs to your tenant. NEXT: spreadsheet_file_read to confirm the change landed.
输入参数id必填tagstitler2_keysourceai_promptfile_sizefolder_idrow_countdeleted_atsheet_countsheet_names另有 5 个
Soft-delete a spreadsheet file: stamps deleted_at on the row so it drops out of the library and folder listings, while the row and its R2 object both survive untouched — there is no purge or restore lane yet, so this cannot be reversed through any current door. Requires the file id; an empty id is refused before anything is touched. NEXT: spreadsheet_file_read to confirm deleted_at is now set — the generic list tool still includes soft-deleted rows.
输入参数id必填tagstitler2_keysourceai_promptfile_sizefolder_idrow_countdeleted_atsheet_countsheet_names另有 4 个
Read one spreadsheet_file by id.
输入参数id必填
List your spreadsheet_file rows (newest first).
输入参数limitcursor
Search your spreadsheet_file rows by text.
输入参数q必填limitcursor
spreadsheet_folder_create
Create a spreadsheet_folder.
输入参数name必填color
spreadsheet_folder_update
Update a spreadsheet_folder you own (optionally compare-and-set via expected_updated_at).
输入参数id必填namecolorexpected_updated_at
spreadsheet_folder_delete
Delete a spreadsheet_folder you own.
输入参数id必填
Read one spreadsheet_folder by id.
输入参数id必填
List your spreadsheet_folder rows (newest first).
输入参数limitcursor
List your sticky_note rows (newest first).
输入参数limitcursor
Update a sticky_note you own (optionally compare-and-set via expected_updated_at).
输入参数id必填colorwidthheightcontentz_indexposition_xposition_ytriggers_atexpected_updated_at
Delete a sticky_note you own.
输入参数id必填
Read this tenant's sticky notes whose reminder time (triggers_at) has arrived — the poll the desktop host runs to know what to fire as a local notification, since the web itself has no send channel. Read-only, no arguments: now is always the server's clock, never a caller-supplied value, and only notes with triggers_at set and <= now come back, soonest-due first, capped at 200. NEXT: sticky_note_dismiss clears triggers_at once you've notified, so the same note stops showing up here.
输入参数colorwidthheightcontentz_indexposition_xposition_ytriggers_at
Clear a sticky note's reminder (triggers_at back to NULL) so it drops out of the sticky_note_due poll — call this after the host fires the local notification for it. Runs through the same tenant-scoped write path as every entity update, but via a clear-properties op: ordinary updates ignore null values, so this is the only way to null the column. Idempotent — dismissing an already-cleared note just re-nulls a NULL and succeeds. NEXT: sticky_note_due to see what's still outstanding.
输入参数id必填colorwidthheightcontentz_indexposition_xposition_ytriggers_at
Create a stock_item.
输入参数name必填unitnotescategoryquantityis_activeexpiry_datesell_price_centscost_per_unit_centslow_stock_threshold
Update a stock_item you own (optionally compare-and-set via expected_updated_at).
输入参数id必填nameunitnotescategoryquantityis_activeexpiry_datesell_price_centscost_per_unit_centsexpected_updated_atlow_stock_threshold
Soft-delete a stock item by id: sets is_active to 0 while its movements-ledger history stays intact. stock_item_adjust then refuses the id as NOT_FOUND and stops resolving it by name, so a later delivery under the same name creates a fresh item instead of reviving this one. stock_item_list and stock_item_read still return it with is_active: 0 — only the dashboard's stats header excludes it. Restore by running a normal update that sets is_active back to 1; there is no separate restore door.
输入参数id必填nameunitnotescategoryquantityis_activeexpiry_datesell_price_centscost_per_unit_centslow_stock_threshold
Read one stock_item by id.
输入参数id必填
List your stock_item rows (newest first).
输入参数limitcursor
Search your stock_item rows by text.
输入参数q必填limitcursor
Create a studio_character.
输入参数name必填color_tagdescription必填prompt_suffixreference_image_key
Read one studio_character by id.
输入参数id必填
List your studio_character rows (newest first).
输入参数limitcursor
Update a studio_character you own (optionally compare-and-set via expected_updated_at).
输入参数id必填namecolor_tagdescriptionprompt_suffixexpected_updated_atreference_image_key
Delete a studio_character you own.
输入参数id必填
studio_environment_create
Create a studio_environment.
输入参数name必填color_tagdescription必填prompt_suffixreference_image_key
Read one studio_environment by id.
输入参数id必填
List your studio_environment rows (newest first).
输入参数limitcursor
studio_environment_update
Update a studio_environment you own (optionally compare-and-set via expected_updated_at).
输入参数id必填namecolor_tagdescriptionprompt_suffixexpected_updated_atreference_image_key
studio_environment_delete
Delete a studio_environment you own.
输入参数id必填
Create a video studio project — the composition document (scenes, tracks, clips, captions) starts empty and is built up afterward through the studio.* director tools. thumbnail_key is server-owned: send thumbnail_data_url instead, and this door externalizes it into a content-addressed R2 key through the media hygiene kit (magic bytes decide the type; SVG refuses). Free. NEXT: studio_project_read to verify.
输入参数namestatusthumbnail_keythumbnail_data_url
Read one studio_project by id.
输入参数id必填
List your studio_project rows (newest first).
输入参数limitcursor
Rename a project, change its status, or replace its thumbnail on a project you own — send thumbnail_data_url, never thumbnail_key, which is server-owned and computed by this door the same way studio_project_create does. status here is UI-summary-only by design: it never gates render or generation, which are tracked separately by the export job row and the composition document's own scene status. Free. NOT_FOUND when the id is outside your scope — list first with studio_project_list.
输入参数id必填namestatusthumbnail_keythumbnail_data_urlexpected_updated_at