Your Customers' API

Each Customer gets your API, MCP and Docs on your own domain, with their own key, Limit and Tenant, and a sign-in that sets what people and agents may do.

Reads
every Noun · Offer.pro
Generates
5 outputs
Open

Your own domain

Every Customer meets Leaseclock at leaseclock.com. The definition that runs your Admin also serves your Customers' API, MCP server and Docs there, under your name.

InterfaceOn leaseclock.comEach Customer gets
APIhttps://leaseclock.com/api18 operations on Leases and Units
MCPhttps://leaseclock.com/mcpsearch, fetch and do
Docshttps://leaseclock.com/docsA page per Noun and Verb, each with a Markdown twin

No address, key, header or refusal names the platform. When you publish a new Version, the API, MCP and Docs move to it together.

Keys and Limits

Each Customer holds API Keys for their own Tenant. A key signs calls to the API and MCP, and rolling or revoking one is a single Verb, from the Admin or any Interface.

The Offer a Customer buys sets their Limits. Leaseclock Pro writes limits: { Unit: 200 }, so the 201st Unit is refused before anything runs:

Terminal
curl -X POST https://leaseclock.com/api/units \
  -H "authorization: Bearer $LEASECLOCK_KEY" -H 'content-type: application/json' \
  -d '{"label":"14C","building":"Harbor Court"}'
403 · application/problem+json
{
  "type": "https://startupbuilder.dev/errors/limit-exceeded",
  "status": 403,
  "title": "Limit exceeded",
  "detail": "Leaseclock Pro holds up to 200 units; this Tenant holds 200"
}

A refused call stores nothing and costs nothing. The count belongs to the Tenant, and every Interface refuses with the same code: the SDK, MCP's do and the SaaS App's Create form. The refusal catalog lists each code with its fix, and Get paid with Stripe sells the Offer.

Tenants

Each Customer gets one Tenant: their own Leases and Units, apart from every other Customer's. The key carries the Tenant, so no request names it.

The Property manager's key lists their Tenant's active Leases, soonest first:

Terminal
curl -G https://leaseclock.com/api/leases -H "authorization: Bearer $LEASECLOCK_KEY" \
  --data-urlencode status=active --data-urlencode sort=endsOn
200 · application/json
{
  "leases": [
    {
      "$id": "https://leaseclock.com/api/leases/4b",
      "$type": "Lease",
      "unit": "4b",
      "renter": "maya.ortiz@example.com",
      "endsOn": "2026-11-15",
      "status": "active"
    },
    {
      "$id": "https://leaseclock.com/api/leases/12",
      "$type": "Lease",
      "unit": "12",
      "renter": "sam.lee@example.com",
      "endsOn": "2027-03-31",
      "status": "active"
    }
  ],
  "meta": { "total": 2 }
}

The API applies the Tenant to every call, so the SaaS App, the SDK and an agent see these records and no others. A record from another Tenant answers 404, as if it did not exist. Your team's Admin reaches every Tenant; a Customer's key reaches one.

Customer sign-in

Customers sign in on leaseclock.com, under Leaseclock's name and theme. Each person holds one Access level in their Tenant, and the API checks it on every call.

PersonaAccess levelIn their Tenant
Property managerownerBuys Leaseclock Pro and invites the team
Leasing coordinatormemberRecords Leases and renews them

The Property manager adds the Leasing coordinator with Tenant.invite. Signed in, each person works in the SaaS App: your Admin's screens, scoped to their Tenant and Access level. A screen hides what an Access level forbids, and the API refuses it either way.

Your Customers' agents

A Customer's agent connects to https://leaseclock.com/mcp and signs in as its person. It holds that person's Access level in that person's Tenant, and never more.

Three tools cover every Noun and Verb. search finds records, fetch reads one, and do runs a Verb. The Leasing coordinator's agent finds the Leases ending by November 30, previews each renew in try, and commits once the coordinator agrees.

The agent meets the same refusals a person does, in the same words. At the 201st Unit it reads "Leaseclock Pro holds up to 200 units" and stops.

Contents