Manage Anchor proposals, agreements, invoices, payouts, contacts and webhooks.
Anchor ships in the w6w first-party pack. It declares 33 actions, 2 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.anchorAnchor is billing and proposal software for service businesses: you send a client a proposal, they approve and sign it, and it becomes an agreement that bills on a schedule.
This app covers that whole lifecycle through Anchor’s public API: create contacts, clone a proposal template into a draft, publish it to the client, withdraw and republish it for edits, and approve on the client’s behalf. Once an agreement exists you can read it, rename it, add credits and submit one-off or out-of-scope charges to issue an invoice now or on a future date.
For money coming in, read invoices and payouts, including the invoice charges that make up each payout, and filter by status, issue date or QuickBooks and Xero sync state. Webhook subscribe and unsubscribe actions let a workflow react to proposal, agreement, invoice and payout events instead of polling.
Three routes to the same 33 actions. The Workflow tab is generated from Anchor's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
adhoc-agreement-get-or-create Return the ad-hoc agreement between you and one client contact, creating it if none exists.
agreement-get Fetch a signed agreement (v2 shape): typed billing triggers, pending amendments and signing audit.
business-get Return the Anchor business the API key is bound to — its id and display name.
charges-submit Submit charges for an agreement to generate an invoice now (bill_now) or on a future date (schedule_bill).
contact-create Create a client contact. Uniqueness is per (email, company name): the same email under a different company creates a second contact.
contact-list Page through client contacts, optionally filtered by search text or accessibility.
credit-add Add a credit (negative charge) to a client's account under an agreement. It reduces the total due on future invoices.
invoice-get Fetch one invoice: line items, payment information, accounting sync status and amount breakdown.
invoice-list Page through invoices issued by your business, with filters for status, dates and accounting sync.
legal-terms-list Page through your legal-terms documents (terms of service, privacy policy, MSA).
payout-invoice-list List the invoice charges (payments, refunds, disputes) that make up one payout.
proposal-approve-on-behalf Approve a sent proposal as the service provider, turning it into an agreement. Irreversible.
proposal-cancel-edit Discard the linked draft's pending edits and restore the proposal. Only valid after Withdraw Proposal For Editing.
proposal-draft-create-from-template Clone a proposal template into a new draft, optionally linked to a client contact.
proposal-draft-get Fetch one proposal draft in full: services, billing configuration, payment settings and legal terms.
proposal-draft-list Page through proposal drafts (work in progress, not yet sent to a client).
proposal-draft-update Change a draft's own fields. Only the fields you send change; services, packages and legal terms are not editable here.
proposal-get Fetch one proposal in full, including client and service-provider details.
proposal-list Page through proposals sent to clients (name, status, client, expiration, progress).
proposal-republish Apply the linked draft's edits and re-send the proposal. Only valid after Withdraw Proposal For Editing.
proposal-template-get Fetch a proposal template: agreement name, services, packages, payment settings and legal-terms references.
proposal-template-list Page through saved proposal templates. Returns id and last-updated time only; fetch one for the full structure.
proposal-withdraw-for-editing Withdraw a published proposal so its linked draft becomes editable. Finish with Republish Proposal or Cancel Proposal Edit.
service-template-list Page through reusable service templates and bundles (name, billing, pricing).
webhook-subscribe Create or update the subscription for a URL; each call REPLACES that URL's event types. The response carries the key for verifying payloads.
webhook-subscription-list List the active webhook subscriptions: target URL and event types.
webhook-unsubscribe Remove a webhook subscription; its URL stops receiving events.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Anchor's real ids.
{
"manifestVersion": "2",
"name": "anchor-example",
"steps": [
{
"id": "adhoc-agreement-get-or-create",
"uses": {
"app": "io.w6w.anchor",
"action": "adhoc-agreement-get-or-create",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"clientContactId": "<clientContactId>"
}
}
]
}adhoc-agreement-get-or-create agreement-get agreement-list agreement-rename business-get +28 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Anchor, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Anchor. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "adhoc-agreement-get-or-create",
payload: {
clientContactId: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action adhoc-agreement-get-or-create --payload '{"clientContactId":"<value>"}' Give an AI agent Anchor — without giving it Anchor's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.anchor#adhoc-agreement-get-or-create",
"input": {
"clientContactId": "<clientContactId>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Anchor connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Anchor's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Anchor itself is MIT, and the runtime that executes it is source-available (FSL).
Anchor declares its own checks, so its health is a property of the app rather than something the host guesses at.
Requests remaining in the current rate-limit window, from GET /me headers.