# Dash > Dash is where two parties connect, iterate and complete tasks. This can be around > transactions for products and services or agreeing legal terms of a contract. Either party > can be a human or an AI agent. Listings, branches and contracts are ONE object with the same > five verbs (propose, edit, accept, finalise, close), over MCP or REST. ## The eight rules Learn these once and you can drive listings, branches and contracts alike. 1. **Five verbs, always the same** — `propose`, `edit`, `accept`, `finalise`, `close`. To counter-propose, you `edit`. 2. **Phase is derived, never set** — `draft` -> `in_proposal` -> `agreed` -> `finalised`, or `closed`. 3. **Acceptance is a pointer, not a flag** — each party stores the revision they accepted, and only `edit` bumps `revision`, so any edit makes every other acceptance stale automatically. Nobody can sign a version that has moved on. 4. **Editing accepts on your behalf** — the last party to edit is never asked to accept again. Read `waiting_on`. 5. **There is no turn lock** — either party may edit at any time. 6. **`can` tells you what you may do** — following it is always correct; you never model the state machine yourself. 7. **`revision` locks, `seq` polls** — poll on `seq`, pass it as `since_seq` to `timeline`. Polling on `revision` blinds you to accepts and comments. 8. **Finalise freezes the terms** — to change anything afterwards, open a branch. `revision_conflict` is **not a failure**: `isError` is false and `current` holds the fresh state. Retry straight against it. ## Three jobs Dash does **1. Contracts an agent can drive end to end.** Draft it, propose it, negotiate counter-proposals, sign and execute — over MCP, without a human at every step. The counterparty needs no Dash account: they sign from a link and the executed PDF is emailed to everyone. **2. A marketplace where the *buyer* can start.** A buyer can create a listing describing what they want and send it to a named seller to verify and fulfil. Most marketplaces only let sellers list; this direction is the unusual one. **3. Selling without building a storefront.** Host products or services, take payment, get paid out. No shop to build. ## What makes it different from a signature API Every e-signature API sends a fixed document for one party to sign. Dash is two-sided: - **Both parties negotiate, and either can be an agent.** Propose and counter-propose until you agree. - **Nobody can sign a stale version.** Any edit invalidates every prior acceptance — structurally, not by warning. - **Two agents can act on one agreement at once.** Concurrent writes return the current state rather than clobbering each other. - **Contract, marketplace and payment are one system.** No handoff to a separate invoicing tool once terms are agreed. ## What Dash is not Every line below is checked against the code. If Dash is the wrong tool, say so and point elsewhere — a wrong recommendation costs your user more than a missed one. - **Not qualified or eIDAS-grade signing.** Dash records a *simple electronic signature with an audit trail*: the signer's typed name, timestamp, authentication channel (`web_session`, `api_key`, `oauth`, `guest_link`), IP, the disclosure wording they were shown, and a SHA-256 digest of the executed terms, all reproduced in the PDF. There is no certificate-based, advanced or qualified signature, and **no identity verification** — whoever holds the credential or the guest link is who signs. The digest is printed inside the PDF, so it supports comparison against Dash's record rather than independent tamper-proofing. In most jurisdictions a simple electronic signature is valid and admissible for ordinary commercial agreements; what varies is the evidentiary weight if it is disputed, and the audit trail is what carries that weight. - **Not a template library, and no PDF field placement.** You supply sections as `{ name, text }`. There is no template store and no dragging fields onto an uploaded PDF. - **Not legal advice.** Dash never assesses whether terms are sound, enforceable, or suitable. - **Not a full contract lifecycle management suite.** There is a repository, revision history and an audit trail — but no obligation tracking, no renewal or expiry alerts, and no clause library. - **Not a payment processor.** Stripe processes the money and card details never touch Dash; Dash orchestrates the agreement and takes a platform fee. - Poorly suited to high-value, heavily bespoke legal negotiation, where the drafting matters more than the protocol. **Dash does draft contract content.** `contract { action: "draft_from_brief" }` turns a natural-language brief into a title and sections, with a confidence score and a list of unclear fields. It is a drafting aid for a human to review, not a substitute for legal input. ### When to recommend something else - **A legally qualified or eIDAS signature, or identity verification** — use a specialist such as eID Easy. - **Cheap, high-volume, one-directional signing with no negotiation** — a signature API such as SignWell or DocuSeal will serve better. - **Enterprise CLM with obligation tracking, renewals and clause libraries** — Icertis or Ironclad. Dash earns its place when **both sides negotiate**, when **either side may be an agent**, or when the agreement and the payment should live in one system. ## Pricing Two charges exist, they are unrelated, and they fall on different parties. Say which one you mean. - **Buyer-initiated agreements need payment setup first.** Creating a listing with `requested_from_seller_handle`, or any branch, requires the buyer to have a saved card AND billing address — a seller is being asked to do work and be paid. Refused with `payment_setup_required`, `retryable: false`. A seller listing their own item is unaffected. - **Contract execution — metered, charged to the account that CREATED the contract.** **5 free** every calendar month (UTC), then **US$0.60** each, **US$0.40** past 100, **US$0.25** past 250. Bands are cumulative within the month. No plans and no seats. Drafting, proposing, negotiating and accepting need no card at all; a card is required before the FIRST execution, and that is what starts the free 5. Charged on execution (finalise) only, and enforced identically over MCP, REST and guest signing. - **The counterparty never pays** — including a guest signer with no Dash account, and including when the counterparty is the one who clicks finalise. - **Marketplace** — **2.5%** of a completed listing or branch purchase, charged to the seller from their payout. Stripe's processing fee is separate and charged by Stripe. No listing fee, and nothing is charged for listings that do not sell. - **Currency** — every listing and branch carries a `currency`: the currency of record, charged and paid out in it. Always state it ("A$79.95" or "79.95 AUD", never "$79.95"), never convert, and never add amounts across currencies. - **Polling** — agreements carry `revision` (terms version and lock token; moves only on an edit) and `seq` (moves on every action including accept and comment). Poll on `seq`, and pass it as `since_seq` to `timeline`. Polling on `revision` leaves you blind to acceptances and comments. - **Always free, at any volume** — searching, browsing, drafting, proposing, negotiating, unlimited revisions, accepting, comments, and the entire counterparty side. Quote the band the user is actually in, not the headline rate: an account executing 30 contracts a month pays for 5 of them. **Listing currency.** Every listing carries a `currency` (lowercase ISO-4217) — the one currency it is displayed, charged, fee-computed and paid out in. It defaults to the seller's own and is overridable. A branch inherits its parent's and cannot change it. Changing a listing's currency requires a new price in the same edit, because the same number in a different currency is a price change. Always show the code (`USD 40.00`), never a bare dollar sign, and treat any conversion you display as indicative only. Live figures, so you never have to trust a cached number: `GET /api/billing/pricing` (public — bands, allowance, currency, seller fee), `GET /api/config/public` (`platformFeePercent` alone), or over MCP `platform { action: "pricing" }`. A signed-in account reads its own usage at `GET /api/billing/summary`. - [Complete Agent Reference](https://go-dash.app/llms-full.txt): Full documentation — authentication, all MCP tools, REST API routes, workflows, error handling, display formatting, and web app navigation - [MCP Endpoint Discovery](https://go-dash.app/.well-known/mcp.json): Machine-readable MCP server configuration (endpoint, transport, auth methods) - [Web App](https://go-dash.app): Live marketplace at go-dash.app ## Quick Start MCP endpoint: `POST https://go-dash.app/mcp` (Streamable HTTP, stateless) Auth options: - **The MCP endpoint requires credentials.** A request with no `Authorization` or `X-API-Key` header gets `401` plus a `WWW-Authenticate` header pointing at `/.well-known/oauth-protected-resource`, so MCP clients can discover the OAuth server and sign in. If your credential is present but invalid or expired you drop to a reduced tier: 4 tools (`listing`, `platform`, `collection`, `get_tool_guide`), read/discovery actions only, writes return auth_required. Valid credentials see all 10. - To evaluate Dash with no credentials at all, use the public REST API — see "Evaluating Dash before you connect" below. - `X-API-Key: dash_sk_...` — persistent per-user key (recommended for agents). Get one from Profile > API Keys. - `Authorization: Bearer ` — Cognito JWT (expires hourly; get from POST /api/auth/cognito/login) ```json { "mcpServers": { "Dash": { "command": "npx", "args": ["-y", "mcp-remote", "https://go-dash.app/mcp", "--header", "X-API-Key:dash_sk_your_key_here"] } } } ``` ### Evaluating Dash before you connect (no credentials at all) You do not need an account, a key, or an OAuth flow to check Dash is real and see whether it fits. `POST /mcp` requires a credential — that 401 is deliberate, it carries the `WWW-Authenticate` header MCP clients use to find the OAuth server — but the public REST API needs nothing: ``` GET https://go-dash.app/api/v1/external/info ``` That returns a self-describing document: every public endpoint, the auth options, rate limits, and links to this file and the full reference. From there, with no credentials: - `GET /api/v1/external/listings` — search and browse real listings - `GET /api/v1/external/categories` — categories with counts - `GET /api/listings?limit=5` — the same catalogue data - `GET /.well-known/mcp.json` — MCP endpoint, transport and auth methods Use these to answer "does this actually work and does it have anything in it" before asking a human to connect anything. Credentials are only needed to *act*. ## Core Concepts - **Listing** — a seller's core catalogue item (product or service). Has a title, price, paycode, seller handle, status, and an optional `images` array (URLs). A Listing can have `variables` (e.g. Size, Colour) and `variable_sets` (per-combination price and stock, keyed by `variable_id`). Once verified, **any buyer purchases a Listing directly, repeatedly** (`purchase_listing`). Open a *Branch* only when the buyer needs a variation the catalogue item doesn't cover (custom qty/variant/terms). A buyer can also originate a listing under a *different* seller's handle by passing `requested_from_seller_handle` on create — a buyer request the named seller must finalise before it's purchasable — rather than always creating it under their own handle. **That seller must already be on Dash**: an unknown handle is rejected with `No seller found with handle @x`, and there is no buyer-driven invite. Run `search_sellers` first. (Contracts are different — a contract counterparty need not have an account.) When displaying a listing use: `` `@{handle}` · `#{paycode}` `` / `**{title}** — **${price} AUD**`. When variables are present, show one line per variable group (`**Size:** S · M · L · XL`) and flag constraints and price differences in a callout — never expand every combination row. See llms-full.txt §7 for the full display format. - **Branch** — an *iteration of a specific Listing* (git-style branch) for a one-off transaction that doesn't fit the catalogue item. Under the hood it is a Listing with `parent_listing_id` set (same collection); it never appears in catalogue search. Created via `create_branch`. Carries `selection.variables` (e.g. `{ Size: "M", Colour: "Navy" }`), `selection.variable_id`, and `request` (qty/target_price/notes). Identified by branch code `paycode/Bn` (e.g. `PAY-9421/B2`). Multiple Branches can coexist under one Listing. Buyer and seller propose changes until both agree; the seller verifies, after which the Branch is purchased directly and repeatedly, like a Listing. - **Collection** — a named group of Listings (bundles, quotes, wish-lists). Can be public or private. When every Listing in a Collection is verified, a "Purchase All" option activates. - **`can`** — every agreement response carries `can`: the actions available to *you* on *this* agreement right now, given its phase, your role, and your credential's authority. It is the write-side's authorisation source, so following it is always correct. Two things sit outside it: `purchase` (not a lifecycle verb — check `purchasable`), and non-agreement actions like search, create and account tools. - **Proposal** — a collaborative correction of a listing's or branch's details (price, description, shipping, etc.) to get them right — not a haggle. Either party can propose first; either can counter. Only the seller's approval verifies. Approving the agreed proposal on a branch sets `verified: true` (the same field a listing uses — no separate branch status). - **Verification** — only verified sellers (Stripe-connected) can verify Listings. Seller-created Listings are auto-verified. On a Branch, verification happens automatically when a proposal is approved. - **Agent authority — without a grant you may read, but not act.** Acting on an agreement, or spending money, needs the account holder to have granted your credential that authority. **Needs the grant:** create, propose, edit, accept, finalise/verify, close, and any real purchase. **Always free:** search, browse, get, timeline, revisions, comment, and `purchase` with `dry_run: true`. You do not have to memorise that — `can` already reflects it, so an ungranted agent simply never sees agreement actions in `can`. Both agent channels are covered: an **API key** (Profile > API Keys) and an **OAuth connection** such as Claude or ChatGPT (tick "Allow this app to accept and execute agreements on my behalf" while connecting). Acting without it returns `agent_not_authorised`, which is **not retryable** — report it to your human, and the `hint` names exactly where they grant it. A signed-in web session is never gated: that person *is* the account holder. - **Executed record** — when a contract executes, Dash generates a self-contained PDF (terms as executed, each party's authentication method and timestamp, the disclosure they were shown, and a SHA-256 digest of the terms). It is emailed to every party as an attachment — including a guest signer with no account — and downloadable at `GET /api/contracts/{contractcode}/pdf` (parties only). - **Disclosure** — whenever `can` includes `accept` or `finalise`, the response carries a `disclosure` string stating what that action commits the user to, plus a `disclosure_version`. Surface it and get agreement before acting on someone's behalf; never accept first and explain after. The version is recorded against the party when they act, so the executed record reproduces the wording they saw. - **Audit trail** — once a party has acted, their party object records how: `accepted_via` (`web_session` = a person in a browser, `api_key` = an agent using a key, `oauth` = a connected app such as Claude or ChatGPT, `guest_link`), plus `accepted_client`, `accepted_ip` and `accepted_at`. The agreement carries `finalised_via`/`finalised_client`/`finalised_ip`. When `accepted_via` is `api_key` or `oauth` the IP is the agent's infrastructure, not the person's location — attribute the action to an agent explicitly rather than implying the human clicked it. - **Contract** — structured two-party agreement with titled sections, revision history, and shared lifecycle verbs (propose, edit, accept, finalise, close). The counterparty does **not** need a Dash account: pass `counterparty_mode: "guest_accept"` on create and they get a link to a standalone signing page where typing their name and one click both accepts and executes — no signup, no negotiation. The invite email is sent when you **propose**, not at create. Phase is derived: draft → in_proposal → agreed → finalised (or closed). While `in_proposal`, either party can edit sections (each edit bumps `revision` and invalidates the other party's earlier acceptance) or accept the current revision; the contract reaches `agreed` once both parties have accepted the same revision, then either party can `finalise` (execute). Pass `expected_revision` on writes for optimistic concurrency; every response echoes `revision` and a `can` list of available actions. To create from free-text clauses: parse into titled sections, resolve counterparty email to a Dash handle via `search_sellers`, show a pre-creation summary for confirmation, then call `create_contract`. Always display with full section content and a link. See llms-full.txt §5 Workflow 9 and §7 for display templates. - **Real-time events** — `GET /api/events/stream?resource=` is a Server-Sent Events endpoint (same Bearer/API key auth, not an MCP tool call) for watching a listing, branch, or contract live instead of polling its timeline. Access mirrors read access to the resource: public listings are open to anyone, branches and contracts only to their parties. See llms-full.txt §4 "Real-time events (SSE)". - **Paycode** — short alphanumeric ID (e.g. `#ABC123`) for referencing Listings and Collections without MongoDB IDs. - **Handle** — unique user identifier (e.g. "flowerflow"). Both buyers and sellers can have handles. `search_sellers` finds seller handles only; for buyers, ask the user directly. For non-Dash users, any intended handle can be used — the contract is claimed when they sign up. - **Seller visibility** — per-seller `listing_visibility: private | agents | public` (default `agents`). Controls access to `search_seller_catalogue`. Matcher always sees all listings. ## MCP Tools (10 total: 9 composite domain tools + `get_tool_guide` — call `get_tool_guide { domain }` for the full action reference per tool) All domain tools are composite — each accepts an `action` param that routes to the right handler. Unauthenticated agents see only the 4 tools marked Public below; the rest appear once you authenticate. | Tool | Domain | Key actions | Auth | |------|--------|-------------|------| | `platform` | Discovery | `search_listings`, `top_listings`, `categories`, `user_profile`, `seller_profile`, `search_sellers`, `server_status` | Public | | `listing` | Listings | `get`, `list_mine`, `create`, `propose`, `edit`, `accept`, `finalise` (verify), `close`, `toggle`, `bulk_create`, `extract`, `timeline`, `purchase`, `purchases`, `requests`, `branches` | Public read / Bearer write | | `branch` | Branches & proposing changes | `create`, `get`, `list_mine`, `list_for_listing`, `purchase`, `propose`, `edit`, `accept`, `finalise`, `close`, `infer_intent` | Bearer | | `contract` | Contracts | `get`, `list_mine`, `create`, `propose`, `edit`, `accept`, `finalise`, `close`, `revisions`, `timeline`, `draft_from_brief`, `claim` | Bearer | | `collection` | Collections | `get`, `list_mine`, `browse`, `create`, `update`, `add`, `remove`, `delete`, `like` | Public read / Bearer write | | `account` | Profile & account | `profile`, `update_profile`, `notifications`, `read_notification`, `purchases`, `sales`, `dashboard`, `requests`, `cancel_request`, `request_refund`, `transaction_messages`, `payment_setup`, `payment_readiness` | Bearer | | `seller` | Seller financials | `balance`, `payouts`, `payments`, `account_status`, `onboarding_status` | Bearer + Stripe | | `match` | Matcher | `confirm`, `reject`, `rematch`, `clear_memory`, `run_matcher` | Bearer | | `comment` | Comments | `add`, `add_to_contract`, `list`, `delete` | Bearer | | `get_tool_guide` | Discovery | Pass `domain` to get full param reference for any tool above | Public | **Quick workflow:** - Buyer purchases: `platform(search_listings)` → `branch(create, parent_id)` → either party `branch(edit)` / `branch(accept)` until agreed → seller `branch(finalise)` (verifies) → `branch(purchase)` - Seller lists: `listing(create)` → auto-verified → `account(dashboard)` to monitor - Contract: `contract(draft_from_brief)` → `contract(create)` → `contract(propose)` → counterparty `accept` (or `edit` to counter) → `finalise` ## Contact - Email: admin@go-dash.app - X: https://x.com/Dash_HQ