API Report Card · Maintenance · Methodology v1.1
Mason
NOTE: This grade is produced by an AI analysis run against the same published grading file, which you can download and check here. The scope is deliberately narrow: API and data access. It is not Peter Lohmann's opinion of Mason as a software platform, and it says nothing about Mason's features, reliability, interface, support, or standing in the industry.
Where the points came from.
Five categories, each worth a fixed share of the 100 points. A category earns the fraction of its checks it passes, times its maximum.
Functional Coverage
Design & Reliability
Access Control
Docs & AI-Ready
Access & Cost
Letter grades are absolute, never curved.
The same numeric bands apply to every platform. Nothing here is scored relative to the rest of the board.
What this means for you.
One paragraph per category, in plain language.
1 · Functional Coverage
You can see everything Mason knows about a work order, but you cannot do anything to it through the API. All 25 published operations are GET requests, so there is no creating, assigning, approving, or closing, and Mason's own guide says so in as many words: use only the documented read-only endpoints, and do not infer write capabilities from response fields. Ten of the eleven core objects are there to read, work orders, status, assignment, vendors, scheduling, residents, units and properties, estimates, invoices and owner approval, with tags the one absentee. To catch changes you poll an updated-since filter or read the activity log, both confirmed live. There is no push.
See technical details2 · Design & Reliability
The technical build is clean and predictable. A live check of 126 fields across 250 records found zero type mismatches and zero undeclared fields, money arrives as integer cents rather than floating point, and cursor pagination held its documented ordering across three pages with no duplicates and no surprises at the last page. What is missing is everything you would want when something goes wrong. Forty requests in a row produced no rate-limit headers and the docs mention no limits at all, so throttling is a mystery until you hit it. Errors return one human-readable sentence with no machine-readable code to branch on. The version sits in the path with no compatibility policy behind it, the only request id on a response belongs to the hosting platform rather than to Mason, and there is no status page to check when it is down.
See technical details3 · Access Control
One all-or-nothing token for your whole account, issued by Mason over e-mail. There is no scoping by resource, action or role, no documented way to hold a second key, and no self-serve rotation, so anything you hand the token to sees every call, text, e-mail, invoice and contact Mason has. Revocation does exist, just not in your hands: the documented 401 covers an inactive or expired token, which means shutting one off is a support request. A separate test workspace exists inside the product, but no test credential is documented and nothing says whether a production token can reach it.
See technical details4 · Docs & AI-Ready
This is the API's strongest area. The whole contract is published as an OpenAPI 3.1 specification that serves without a token and matched live responses exactly, alongside a single Markdown guide of the entire API written with AI agents in mind, right down to a copy-the-docs-as-Markdown affordance and an agent guidance section. Point a coding tool at either one and it should build correctly the first time. Two gaps keep it from full marks: there is not one worked response example anywhere, and there is no changelog or release note, so you can tell that the contract changed but not what changed.
See technical details5 · Access & Cost
Nothing about the API is gated or billed. The token came with the operator's existing subscription, no tier change and no charge, the plan tiers say nothing about API access, and the specification is public with no token required. What you cannot do is get the key yourself. There is no API or developer section in the product, so you ask Mason and wait for a person to send you one.
See technical detailsEvery check, and why it scored that way.
The same 27 checks are applied to every platform. What changes is which are N-A and what the core objects mean for that kind of software. Each mark below is quoted from the run's own report. Marks are AI-generated and cover API access only.
Category 1 · Functional Coverage
1.9 / 15Object coverage
weighted coverage = 47.6% (10 present-read-only × 0.5 = 10.0 ÷ Σweight 21). Every critical and important object is present but read-only where writes are operationally expected; tags absent. Citations in the table above (OpenAPI paths). Falls just under the 0.50 partial floor.
Core operational actions
weighted coverage = 0%. No create/update operation exists for any object or workflow; all 25 operations are GET (openapi.json paths; api.md "read-only GET endpoints"). Documentation-graded: nothing to observe.
Delete or lifecycle actions
weighted coverage = 0%. Status change, cancel, close, approve, reject are all visible as fields but none is invocable (no PATCH/POST/DELETE in the contract). Documentation-graded.
Change notification
no webhooks or events are offered; the only mechanism is incremental polling, which is efficient and was live-verified: updatedAfter on /work-orders (api.md line 38; live: updatedAfter=<3 days ago> honoured, 0 records, all lastUpdated ≥ bound), plus GET /work-order-activity-logs with createdAfter as an event stream (live: 5 records, fields eventType, internalWorkOrderId, timestamp). Documented limitation: "Related-record changes do not necessarily advance this timestamp" and "Incremental date bounds… do not provide complete historical changes" (api.md lines 27, 38).
Category 2 · Design & Reliability
5.6 / 10Modern API conventions
resource-oriented REST over HTTPS, JSON envelopes {data, pagination}, standard GET on collections and /{id}, query-string filters (openapi.json; live 2026-09-22: /work-orders?limit=5 → 200).
Consistent typing
live-vs-schema check across work-orders, invoices, contacts, properties, units (250 records, 126 fields): 0 mismatches, 0 undeclared fields; nulls declared explicitly via anyOf [type, null]; money is integer cents (Invoice.totalAmount/subtotal/tax, Estimate.estimateAmount/approvedAmount). Limitation: two documented numeric-as-string fields — Invoice.selectedMarkupPercentage and Invoice.selectedDiscountPercentage, "decimal string; 10 means ten percent" — a number that does not stay a number, confined to non-core fields.
Structured errors
correct status semantics and a consistent JSON envelope, but no machine-readable error code. Schema Error = {error: string} only ("Human-readable error message"). Observed: 401 {"error":"Invalid API token"}, 401 {"error":"Missing or invalid Authorization header"}, 404 {"error":"Not found"} (random UUID and malformed ID alike), 404 {"error":"Unknown resource \"…\""}, 400 on /on-call-coverage without start/end.
Duplicate prevention
purely read-only API.
Graceful handling under load
no 429, Retry-After, or backoff guidance anywhere in openapi.json or api.md (keyword scan: 0 hits). Live: 40 sequential requests → 40 × 200, no rate-limit headers of any kind. Throttling behaviour is undocumented and unobservable.
Pagination for large collections
documented opaque-cursor pagination with hasMore/nextCursor, a stated ordering guarantee ("ordered by createdAt descending, then by ID descending"), and a documented cap (limit clamped 1–100, default 50) (api.md lines 17, 27, 31–32; Pagination schema). Live: 3 pages, createdAt non-increasing, 0 duplicate IDs; narrow filter → hasMore=false and nextCursor omitted exactly as documented; limit=abc→50, limit=1000→100, limit=0→50 all as documented.
Bulk or incremental export
incremental sync is possible on standard list endpoints (updatedAfter+updatedBefore on 7 of 12 list endpoints; createdAfter on 11) with cursor pagination, but there is no dedicated bulk/export path, and the docs state the incremental bounds "do not provide complete historical changes or a snapshot across pages" and that related-record changes may not advance the timestamp (api.md line 27, 38).
Webhook security and delivery
no webhooks or events offered (already penalised in C1.4).
Concurrency and conflict control
purely read-only API.
Versioning and backward compatibility
explicit path version /api/external/v2, a v1 contract referenced ("v1 retains its legacy numeric-or-null priority contract"), and a contract-revision identifier 2-b0dfb930aad19685 (api.md line 5; openapi info.version). No compatibility policy, no definition of breaking vs non-breaking, no deprecation window.
Request traceability
every response carries X-Vercel-Id (e.g. sfo1::pdx1::s7x5x-1790041782825-8ae9427d5609, live headers 2026-09-22) but it is undocumented and is the hosting platform's identifier; whether Mason support can use it is unverified.
Service availability and status transparency
no public status page (status.thisismason.com / status.enduring-labs.com do not resolve; no link on the docs page). Terms §5: "We strive to maintain 99.9% uptime for the Service. Scheduled maintenance windows will be communicated in advance." Scored as an availability commitment that exists only inside the contract; it is a target, not a remedy-backed SLA.
Category 3 · Access Control
1.3 / 5Read-only credentials
the whole API is read-only.
Scoped credentials
one token "scoped to your property management account" (openapi securitySchemes.bearerAuth; api.md line 7). No resource, action, or role scoping exists; the vendor's own issuance note warns the token "can access a lot of data."
Multiple keys
no documented way to obtain more than one token; the docs describe a single vendor-provided token and the product has no key-management surface (item 7).
Rotation and revocation
no self-serve mechanism; tokens are issued by the vendor by e-mail (item 9). Server-side deactivation demonstrably exists — the 401 response is documented for an "inactive, or expired bearer token" (openapi /work-orders 401 description) — so revocation is a support-mediated process, not an absent one.
Test and production isolation
a separate Test workspace exists in the product ("Switch to Test / Toggle Test/Live PM", item 7), but no test credential is documented, the docs never mention a sandbox, and whether the production token can reach the test workspace is undocumented. Mason itself warns "Mailboxes are shared with your test workspace."
Category 4 · Docs & AI-Ready
3.8 / 5Complete self-serve reference
the public reference is complete on authentication, every endpoint, every parameter (with semantics such as clamping and invalid-date behaviour), and response schemas, plus one worked curl request (docs page; api.md). Limitation: zero worked response examples — openapi.json contains no example/examples keys and api.md gives response shapes only as { data: WorkOrder[], pagination: Pagination }.
Reliable machine-consumable integration path
public OpenAPI 3.1 specification, complete for all 25 operations, served without a token, and verified against live responses with zero type or field drift (typing check above). No SDK or MCP server found (not required for yes).
AI-readable documentation
api.md is a single Markdown corpus of the entire API, published with explicit "give the docs to your agent… Copy docs as Markdown" affordances and an "Agent guidance" section (docs page; api.md line 10).
Kept current
the contract carries a revision identifier (2-b0dfb930aad19685) so change is detectable, but there is no changelog, release notes, or deprecation notice (probes for /docs/changelog → 404; /openapi.json served cache-control: no-store with no ETag/Last-Modified despite the spec's own note that "ETag supports identifying the published document").
Category 5 · Access & Cost
7.5 / 15Self-serve API key
credentials are manually provisioned by the vendor. Docs: "Mason provides a bearer token" (passive, vendor-issued); the product's Settings page has no API or developer section (item 7); the operator's token arrived by e-mail from the vendor's founder a week after asking (items 9; thread [mail thread id withheld], asked 2026-09-04, promised 2026-09-15, delivered 2026-09-22 UTC).
Not commercially gated
the token was issued on the operator's existing subscription with no tier change and no charge mentioned; neither the docs nor the "Plans" section (After-Hours / Intake / Full Suite / In-House) ties API access to a tier; the specification is public ("Public documentation requires no token").
What works
- A public OpenAPI 3.1 specification, complete for all 25 operations and served without a token
- Zero type or field drift: 126 fields across 250 live records matched the schema exactly
- Money is integer cents, and nulls are declared explicitly rather than implied
- Cursor pagination with a documented ordering guarantee, verified across three pages
- A single Markdown guide of the whole API, published for AI agents to read
- Incremental polling works: updated-since and created-since filters honoured live
- Correct status codes on every deliberate error, including 400, 401 and 404
- An activity log endpoint that reads as an event stream of work-order changes
- No tier gate: the token came with the existing subscription at no extra charge
What to watch
- Read-only: all 25 operations are GET, so nothing can be created, assigned, approved or closed
- No webhooks, so every change has to be found by polling
- Mason's own docs warn that incremental filters miss complete historical changes
- One vendor-issued token per account, with no scoping and no second key
- No self-serve key: you e-mail Mason and wait for a person to send one
- No self-serve rotation either, so cutting off access is a support request
- No rate limits documented, and 40 requests in a row returned no limit headers
- Errors carry a sentence but no machine-readable code to branch on
- No changelog or release notes, so you cannot see what changed between revisions
- No status page: neither status subdomain resolves
- No worked response examples in the docs or the specification
- Two percentage fields are typed as decimal strings while all money is integer cents
Check it yourself.
Both files behind this page, in full.
NOTE: Grades are AI-generated from the published grading file, and cover API access only.
Mason’s full report
The complete markdown report this page is built from, including the evidence packet, the run metadata and every check in full.
Download the Mason reportThe grading file
The exact rubric behind every score on this page. Same file, every platform. Run it yourself and compare.
Download the methodologyFound a factual error in your grade?
Tell us and we will fix it. Every mark on this page traces to a specific piece of first-party evidence or a live API call, and the full report is published so you can see exactly what was checked and what it was checked against.
Confirmed factual errors are corrected immediately.
Everything else waits. We do not rescore piecemeal on request, because a board where some vendors have been re-run and others have not is not a fair comparison. Shipped improvements, changed documentation and disagreements about judgement all go into the next full rerun.
Contact us with a factual errorMethodology inspired by SaaStr’s AI Agent API Report Card.