API Report Card · PM Software · Methodology v1.1
Propertyware
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
Almost everything your business runs on is reachable, and you can write to it, not just read it: leases, charges, payments, bills, work orders, owners and tenants. Two real gaps: there is no reconciliation object at all, so bank reconciliation stays a manual job in the product, and there is no way to be told when something changes. Every integration you build will be a scheduled poll, and it will silently miss deletions. The bigger practical brake is that deleting or closing anything requires Propertyware to enrol you in a beta program first. Both test keys demonstrated it: without that enrolment, your automation can create and update but can never clean up after itself.
2 · Design & Reliability
The shape of the API is fine. It is proper REST, it pages predictably, the version contract is clear, and there is a real status page that calls out the API separately. The operability layer underneath is where it loses most of its points, and the misses compound. Nothing stops a retried payment from posting twice. Nothing stops two integrations from overwriting each other on the same lease. And when something does go wrong there is no request id to give support. For a read-and-report integration none of that matters much; for anything that writes money into your ledger, you have to build the safety rails yourself: your own de-duplication keys, your own write serialisation, your own logging.
3 · Access Control
This is the strongest part of the API and the part that matters most if you are going to point an AI agent at your data. You can create a key that can only read, or only touch certain records, hand it to a vendor or an agent, and delete it the moment you want the access gone, all yourself, in the product, without calling anyone. The one soft spot is testing: a sandbox exists, but you have to email Sales Ops Support to get one, and no developer document explains how it is kept apart from live data, so prove that for yourself before you trust it.
4 · Docs & AI-Ready
A developer can sit down with this documentation and build, and the OpenAPI file means your tooling can generate most of the client code for you. Two things will cost you time. The reference under-declares what the API actually requires, so expect a round of trial and error on every create endpoint; the graders hit it immediately on contacts. And if you plan to point an AI coding assistant at these docs, it cannot read them: the whole documentation site is blocked to crawlers and the specification has no fetchable address, so you will have to download the file by hand and give it to the tool yourself.
5 · Access & Cost
Getting a key is genuinely easy: you make it yourself in the product in about a minute, and you can make several. The catch is cost. The API is a paid add-on at a dollar per unit per month on top of whatever you already pay, which on the Basic package doubles your per-unit price. And having API access does not include being able to delete or close anything; that needs a separate conversation with support to join a beta. Budget for the add-on, and ask about beta enrolment in the same conversation.
Every 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.
Category 1 · Functional Coverage
11.3 / 15Object coverage
weighted coverage = 85.5%, no critical object absent. Presence and operations cited per object in the coverage classification above; every collection was additionally confirmed live on 2026-09-14 (X-Total-Count: portfolios 6, buildings 8, units 20, leases 3, contacts 30, vendors 12, work orders 11, bills 69, GL accounts 59, lease charges 4, lease payments 4, owner draws 1, prospects 1, inspections 0). [app.propertyware.com/pw/apidocs — paths inventory; live GETs against api.propertyware.com/pw/api/rest/v1, 2026-09-14]
Core operational actions
weighted coverage = 85.2% over the predetermined mutable objects and mutable workflows (the "read core records" workflow and the computed general-ledger transaction object are N-A within this write sub-map). All three predetermined critical write workflows are present and documented, and none is absent. Reconciliation note: run 1 originally scored this partial at 81.4% using an objects-only sub-map; runs 2 and 3 independently included the workflows, as the methodology's phrase "mutable workflows/objects" directs, and both cleared the 0.85 threshold. Resolved to yes. The sub-map's membership is underspecified in methodology v1.1 — see the disagreements section. Deductions within the map: POST /buildings returned HTTP 500 on five distinct payloads, including values mirrored exactly from existing records in the same tenant, while the same credential created a contact successfully — a server-side fault, not a permission failure; conversations are creatable only on leases and prospects; associations are effectively read-only; reconciliation and inventory have no write path. Create and update were observed live: POST /contacts → 201 (id [test contact id withheld]), PATCH /contacts/[test contact id withheld] → 200 with the change confirmed by read-back. [live write log, 2026-09-14; POST/PUT/PATCH operations per the spec]
Delete or lifecycle actions
weighted coverage = 61.8%, no critical lifecycle action absent. Lease lifecycle is genuinely well covered: PATCH /leases accepts status, moveOutDate, noticeGivenDate, scheduleMoveOutDate and reasonForLeaving, with GET /leases/statuses enumerating the states. Everything else is throttled by one gate: all 18 DELETE operations plus PUT /workorders/closeworkorder/{id} carry "Write access is only available to customers who have opted in to our beta program. Please reach out to support if you'd like to be included." — 25 of the 99 write operations in the spec. Live-observed: DELETE /contacts/{id} returned 404 for both the write key and the delete key, on a record confirmed present by a 200 GET. Documentation-graded and flagged — the capability is documented, but its behaviour when enabled could not be observed. [spec operation descriptions; live write log, 2026-09-14]
Change notification
no webhooks, events or subscriptions exist anywhere in the API (webhook and subscription each appear 0 times across the full spec; no events tag; targeted first-party search during the verification pass found no webhook documentation on either domain). The only mechanism is incremental polling, and it is a good one: all 34 collection endpoints carry an identical lastModifiedDateTimeStart / lastModifiedDateTimeEnd pair with offset/limit and orderby, with zero exceptions. Verified live on /leases: unfiltered X-Total-Count 3; lastModifiedDateTimeStart=2026-01-01 → 2, earliest lastModifiedDateTime 2026-07-10T22:45:49Z; …Start=2030-01-01 → 0. This detects creates and updates but not deletes — a removed record simply disappears, with no tombstone or deleted-since filter. [spec parameter inventory; live queries 2026-09-14]
Category 2 · Design & Reliability
5.9 / 10Modern API conventions
resource-oriented REST over HTTPS with standard verbs (GET 78, POST 41, PUT 30, PATCH 10, DELETE 18), JSON payloads, standard status codes, and a published OpenAPI 3.0.0 document. Docs: "The Propertyware API is built upon standard REST conventions. It's designed to use consistent resource-oriented URLs, accept and return JSON-encoded messages, and use standard HTTP status codes and verbs." Confirmed live throughout the battery. [spec info.description § API Overview; live calls 2026-09-14]
Consistent typing
core financial and identity fields are properly typed and matched live reads: ChargeDTO.amount and PaymentDTO.amount are number/double, ids are integer/int64, dates are string/date, LeaseDTO.active is a real boolean. The limitation is a small set of non-core inconsistencies: BuildingDTO.targetDeposit is a string while its replacement targetDepositAmount is number/double (the spec itself marks the former deprecated); SaveBuildingDTO.publishedForRent is a string enum ["Yes","No"] where a boolean is meant, alongside real booleans like active on the same object; managementFeeType (string) is deprecated in favour of managementFeesType; and GET /health declares content-type: application/json but returns the bare non-JSON literal Success. [spec component schemas; live GET /health 2026-09-14]
Structured errors
a structured envelope is declared (ErrorResponse = {errorCode, userMessage, errors[]}) and referenced by 400/401/403 on all 177 operations, and at its best it is genuinely good: POST /contacts with a missing address returned 400 with field-level entries {"key":"City","message":"City is required"}. Four exact limitations: (1) errorCode was the constant "1001" on every structured error observed — missing auth headers, not-found, missing required parameter, invalid date range, validation failure and a 500 all returned 1001, so it carries no machine-actionable information; (2) GET /leases?limit=notanumber returned 400 with a completely empty body (content-length: 0, no content-type); (3) a wrong-case path returned a 6,591-byte HTML page, not the JSON envelope; (4) DELETE on a record the caller may not delete returned 404 with userMessage: null, byte-identical to the response for a non-existent id, rather than the 403 the spec declares for that operation. A documentation contradiction was also observed: the docs state that missing credentials return 401, but the API returned 400. [spec ErrorResponse; live error probes 2026-09-14]
Duplicate prevention
idempot appears 0 times in the entire spec; no idempotency key, no request-identifier mechanism, no documented natural idempotency on consequential writes. Observed live: a byte-identical POST /contacts sent twice created two distinct records (ids [test contact id withheld] and [test contact id withheld]); contact count went 30 → 31 → 32. Financially consequential creates — POST /leases/charges, POST /leases/payments, POST /bills/payment — carry no protection against a retried request posting twice. [spec term scan; live write log 2026-09-14]
Graceful handling under load
429 is documented in the Response Codes table with recovery advice ("Too many requests against the API too quickly. We recommend an exponential backoff of your requests"), which is qualitative, not numeric. There is no Retry-After header (Retry-After = 0 occurrences in the spec, and none observed on any live response) and no rate-limit headers of any kind on the responses observed. The concrete numbers — "10 concurrent requests per second", "retry after a short interval (~200ms)" — exist only inside an HTML comment in the spec's description under a heading marked "Rate Limiting (FUTURE)", so they do not render on the public documentation page. [spec info.description § Response Codes and the commented § Rate Limiting (FUTURE); live response headers 2026-09-14]
Pagination for large collections
limit (default 100, maximum 500, larger values coerced to 500) and zero-based offset are documented, with the full result count returned in the X-Total-Count header and orderby=field asc|desc available on every collection for deterministic ordering. Verified live: GET /buildings?limit=2&offset=0&orderby=id asc and offset=2 returned disjoint, correctly ordered id sets against a consistent X-Total-Count: 8. [spec § Pagination and § Sorting Results; live paging 2026-09-14]
Bulk or incremental export
the check's yes clause names "documented incremental sync via updated-since plus pagination" as a qualifying mechanism, and that is exactly what is documented: a lastModifiedDateTimeStart/End window with offset, limit and orderby on all 34 collection endpoints with zero exceptions, a total-count signal in X-Total-Count, all set out under a heading called "Bulk Request Options", and live-verified on /leases. A full dataset is retrievable without per-record calls. Reconciliation note: run 1 originally scored this partial on the competing clause "no dedicated bulk/export path"; runs 2 and 3 independently applied the yes clause. Resolved to yes. Two real ceilings remain and are recorded here rather than in the mark: there is no async export job or dedicated export endpoint (the /bulk endpoints are create-only), pages cap at 500 records, and the general ledger — the dataset most likely to be warehoused — rejects any date window longer than 30 days (GET /accounting/generalledger without a range returned 400 "last modified date range / post date range is invalid or Date range more than 30 Days"; a 25-day window returned 200). A full-year GL extract therefore requires at least twelve sequential windowed pulls per filter. [spec § Bulk Request Options and /accounting/generalledger parameters; live queries 2026-09-14]
Webhook security and delivery reliability
the vendor offers no webhooks or events; their absence is penalised in C1.4 and is not double-counted here. [spec term scan: webhook, subscription = 0; verification-pass search found no first-party webhook documentation]
Concurrency and conflict control
no optimistic concurrency of any kind: ETag and If-Match each appear 0 times in the spec, no version or revision field exists on any DTO, and no 409 conflict semantics are documented (the single occurrence of "409" in the spec is one member of a generic HTTP-status enum inside a DTO, not a declared response). No concurrency limits or behaviour are documented. Two integrations updating the same lease will silently overwrite each other. [spec term scan and response inventory]
Versioning and backward compatibility
an explicit major version is carried in the path (/pw/api/rest/v1) and is mandatory: "Any request submitted without the version in the URL path will result in a 404 error response code." The compatibility policy is written out and enumerated on both sides — backward-compatible changes (new resources, new optional parameters, new response properties, property reordering) apply to the current version, while backwards-incompatible changes (removing or renaming a property, adding a required parameter, changing enum values) trigger a new version with "full reference documentation and an upgrade guide". Notice is committed to: "We'll provide advance notice for all API releases–regardless of the type of modifications being made", and field-level deprecations are marked in the schemas themselves. [spec info.description § API Versioning and § Releasing Changes to the API]
Request traceability
no request or correlation identifier is documented (X-Request, requestId, correlation = 0 occurrences in the spec) and none was present on any live response. Headers observed across every 2xx and 4xx were limited to content-type, content-length, date, server-timing, strict-transport-security, x-content-type-options, vary, and x-total-count on collections. The only per-request token is the Akamai ak_p value embedded in server-timing — a CDN diagnostic, not a documented support identifier. When a call fails you have nothing to hand Propertyware support but a timestamp. [spec term scan; live response headers 2026-09-14]
Service availability and status transparency
https://status.propertyware.com/ is a public Atlassian Statuspage carrying a dedicated "Open API" component alongside the platform, with per-day incident history and a subscribe option; https://status.propertyware.com/uptime publishes monthly uptime percentages (July, August and September 2026 each 100%). [observed 2026-09-14]
Category 3 · Access Control
4.5 / 5Read-only credentials
"You can restrict a key to particular Propertyware entities or to read-only access (GET resources only)." [spec info.description § Keeping API Keys Safe, Recommended Practices]
Scoped credentials
fine-grained resource and action scoping. Key creation is explicitly per-resource: "choose which pieces of Propertyware data you want this API key to have access to by selecting the corresponding radio buttons", and the read-only restriction above scopes by action. The spec documents a required permission on every operation individually — for example GET /accounting/generalledger "Required permission: GENERAL LEDGER – Read", POST /buildings "BUILDINGS – Write", DELETE /contacts/{id} "CONTACTS – Delete" — so the permission model is per-resource-per-verb. Corroborated live: the operator's write key created and updated a contact successfully but was refused on DELETE, while the same key read every collection. [spec § Creating API Keys and § Keeping API Keys Safe; per-operation descriptions; live write log 2026-09-14]
Multiple keys
keys are created individually with a name and description precisely so you can tell them apart: "Enter a clear, memorable name and description for your API key. It'll make it easier to locate the right key when you make a request." Confirmed live: the operator supplied two distinct credential pairs and both authenticated independently against the same org. [spec § Creating API Keys; live calls with both keys 2026-09-14]
Rotation and revocation
self-serve, inside the product, with no support ticket: keys are created and deleted by an administrator at Administration Setup > API Keys, revocation is immediate and enforced ("try to use information that's linked to a deleted key, the API will return a 401 response code"), and regular rotation is a documented recommended practice ("Establish a process to regularly recreate your client IDs and secrets from your Propertyware account"). The limitation worth knowing is that rotation is delete-and-recreate rather than rotate-in-place, so there is no overlap window — but the check measures whether rotation and revocation are self-serve, and they are. [spec § API Keys, § Creating API Keys, § Keeping API Keys Safe]
Test and production isolation
a separate test environment does exist: "Who do I contact to request a sandbox/testing account for API? … You may reach out to Propertyware Sales Ops Support: salesopssupport@propertyware.com" (published 2024-05-13). The exact limitation is that this is the only first-party evidence of it. The API documentation portal never mentions a sandbox; the sole documented base URL is described as "the base URL for production environment API requests"; there is no documented test-versus-live credential scheme, no test-mode flag, and nothing describing how test data is isolated. A sandbox you have to email sales operations to obtain, and that no developer-facing document acknowledges, is a materially weaker separation than a documented one. [support.propertyware.com sandbox article; spec § Base URL]
Category 4 · Docs & AI-Ready
2.5 / 5Complete self-serve reference
the portal at app.propertyware.com/pw/apidocs is public, needs no login, and is genuinely example-rich: all 124 paths and 177 operations, 141 component schemas, per-operation parameters, request and response examples, per-endpoint permission requirements, and a full narrative guide covering authentication, versioning, pagination, sorting, response codes and date formats. The exact limitations, each found by live testing rather than by reading: (1) required fields are under-declared — SaveContactDTO.required lists only firstName and lastName, yet POST /contacts rejected a payload with those two fields, demanding Country, then Address, City, State and Zip, none of which the spec marks required; (2) the GET /accounting/generalledger description instructs you to filter with lastModifiedDateStart/lastModifiedDateEnd, but the declared and working parameter names are lastModifiedDateTimeStart/lastModifiedDateTimeEnd; (3) the general ledger's 30-day range ceiling is enforced but documented nowhere; (4) the rate-limiting section is commented out of the rendered page; (5) SaveBuildingDTO.type is required but has no enum and only a prose list of examples. A developer can build from this, but several core flows require trial-and-error against the live API to discover what the reference does not say. [spec; live probes 2026-09-14]
Reliable machine-consumable integration path
a complete, maintained OpenAPI 3.0.0 specification covering all 177 operations and 141 schemas is published and downloadable from the documentation portal, suitable for code and tool generation; it is complete enough that a third party generates and maintains a full SDK from it. No official SDK and no MCP server were found, but one strong mechanism is sufficient for this check and no extra credit accrues for having more. [app.propertyware.com/pw/apidocs — embedded OpenAPI 3.0.0 document and "Download OpenAPI specification" control]
AI-readable documentation
no qualifying resource exists. llms.txt and llms-full.txt return 404 on both app.propertyware.com and www.propertyware.com; there is no per-endpoint Markdown, no downloadable plain-text or Markdown documentation corpus, and no equivalent first-party format structured for retrieval. The situation is worse than merely absent: app.propertyware.com/robots.txt is User-agent: / Disallow: /pw/, which places the entire* documentation portal off-limits to crawlers — an attempt to fetch the reference through a standard retrieval tool during this run was refused on exactly that basis — and the specification itself has no stable URL, existing only as JavaScript state on a client-rendered page that a human must click a button to export. The OpenAPI document is credited in C4.2 as the machine-consumable integration path and is not counted a second time here. [robots.txt on both domains; 404s on all four llms paths; blocked retrieval attempt 2026-09-14]
Kept current
a real changelog exists and is unusually detailed, running from 2022-09-21 through 2026-05-10 with roughly fortnightly dated entries naming new endpoints, new fields, deprecations and bug fixes, and deprecations are additionally marked inline in the schema field descriptions. The exact limitation is that the cadence has lapsed: after years of entries about two weeks apart, there is nothing in the four months between 2026-05-10 and this run on 2026-09-14, so a reader cannot currently tell whether the API has been stable or whether changes have simply gone unrecorded. [spec info.description § Changelog, entries enumerated 2022-09-21 … 2026-05-10]
Category 5 · Access & Cost
11.3 / 15Self-serve API key
once an account is entitled to API access, an administrator creates credentials themselves with no sales call, support ticket or approval step: "On the API Keys page, click Create API Key… Once finished, click GENERATE KEY. You have successfully created an API key!" The only prerequisite is an administrator role with access to Administration Setup > API Keys. The docs offer a support request as a fallback "if you are having issues", not as a required approval gate. [spec info.description § Enabling the API and § Creating API Keys]
Not commercially gated
two distinct gates, neither of which is a premium-tier lock. First, the API is not included in any package: the pricing page's footnote reads "For Enterprise/API: Add $1 per unit/per month to any package", a surcharge that lands between 50% and 100% on top of the $1.00–$2.00 per-unit subscription depending on tier. It is at least tier-neutral — the add-on is available on Basic as readily as on Premium, so the API does not require a premium plan. Second, and not a pricing matter at all, a meaningful slice of API capability sits behind an opt-in beta: 25 of the 99 write operations, including every one of the 18 DELETE endpoints and PUT /workorders/closeworkorder, carry "Write access is only available to customers who have opted in to our beta program. Please reach out to support if you'd like to be included." That gate was confirmed live — both of the operator's keys, one of them provisioned specifically for delete access, were refused on DELETE with a 404. Neither gate is identity or regulatory verification, so neither is excluded from scoring. [www.propertyware.com/pricing/ footnote; spec operation descriptions; live write log 2026-09-14]
What works
- Read-only and narrowly scoped keys, limited by resource and by action, created self-serve
- Several separately named keys per account, each revocable yourself in the product
- Write access across leases, tenants, charges, payments, bills, owners and work orders
- Create and update verified live: a test contact was created and then updated
- Lease status, notice and move-out dates are all writable through the API
- Predictable pagination with total counts and sorting, verified live
- An updated-since filter on all 34 collections, honoured exactly in live tests
- A written versioning policy that defines breaking changes and promises advance notice
- A public status page with its own Open API component and monthly uptime figures
- A complete public OpenAPI 3.0 specification, 177 operations, no login required
What to watch
- API access is a paid add-on: $1 per unit per month on top of any package
- Every delete, and closing a work order, requires joining an opt-in beta; both test keys were refused
- No idempotency: an identical create sent twice produced two records live
- No webhooks, and polling cannot see records that were deleted
- No concurrency control, so two integrations can silently overwrite each other
- No request id on any response, so support gets nothing but a timestamp
- Every error observed carried the same code, and some came back empty or as an HTML page
- Creating a building failed with a server error on five payloads copied from existing records
- No reconciliation object, and bank accounts exist only as general-ledger account types
- General-ledger reads reject date windows over 30 days, a limit documented nowhere
The bottom line for a property manager
Propertyware's API reaches nearly everything your business actually runs on and lets you write to it: leases, tenants, charges, payments, bills, owners and work orders. Its access controls are strong: you can mint a read-only or narrowly scoped key yourself, hand it to a vendor or an AI agent, and revoke it just as fast. The documentation is solid enough to build from, the versioning contract is clear, and a real status page tracks the Open API separately from the platform. What holds the score to a low C- is the operational plumbing underneath. There are no webhooks, so every integration is a scheduled poll that quietly misses deletions. There is no idempotency, so a retried request can post a charge or a payment twice. There is no concurrency control, so two integrations editing the same lease overwrite each other. And there is no request id, so when something breaks you have nothing but a timestamp to give support. Two access facts belong in your budgeting: the API is a paid add-on at $1 per unit per month, which doubles the per-unit cost on the Basic package, and API access does not include deleting or closing records, which sits behind an opt-in beta you have to ask support to join. Propertyware is a property-management-specialized system of record, not a bank: its bank accounts are general-ledger accounts inside the accounting system. Security-deposit segregation is configurable, but no first-party documentation describes trust accounting or reconciliation as an API workflow, so bank reconciliation stays a manual job inside the product. Workable for syncing and reporting, but it needs your own safety rails before you let it write money.
Check it yourself.
Both files behind this page, in full.
Propertyware’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 Propertyware 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. Sponsored by Column.