API keys
Send Authorization: Bearer <key>. Keys are hashed at rest; the raw value is revealed once on creation. Later list responses cannot retrieve it. Revoke a compromised key and create a replacement.
TenantPoint / Developers
TENANTPOINT DEVELOPER PLATFORM · PUBLIC ALPHA
Connect commercial property records, vendors, and work orders to your team’s tools through documented, scoped resources. Use workspace-scoped API keys, a synthetic sandbox, and signed webhooks—not browser credentials or an unrestricted accounting API.
The public API is alpha, not an unrestricted general-availability promise. Portfolio and Professional include developer access; Custom access is configured by agreement. Owner does not include the API. An active eligible plan and enabled workspace access are required.
An Owner or Admin can check availability in Settings → Developers and create scoped credentials there. Start with the isolated sandbox before accessing operational records. If the panel reports access unavailable, verify the selected workspace and plan, then contact TenantPoint; do not bypass the access check. See plan quotas and the private, invitation-based Zapier integration.
The documented resource catalog below is authoritative. Do not assume undocumented rent-payment, financial-provider, general-ledger, or messaging operations are available through the API.
tp_test_ key.TENANTPOINT_API_ORIGIN to the API origin approved for your environment and load TENANTPOINT_API_KEY from your local secret manager.curl "$TENANTPOINT_API_ORIGIN/v1/account" \ -H "Authorization: Bearer $TENANTPOINT_API_KEY" curl "$TENANTPOINT_API_ORIGIN/v1/vendors?limit=10" \ -H "Authorization: Bearer $TENANTPOINT_API_KEY"
The response uses a data envelope containing the account, bound workspace and environment. Keep API keys out of browser code, URLs, logs and source control. Dedicated API and developer hostnames are not configured by this guide; use only the operator-approved origin.
Send Authorization: Bearer <key>. Keys are hashed at rest; the raw value is revealed once on creation. Later list responses cannot retrieve it. Revoke a compromised key and create a replacement.
tp_live_ keys access the live workspace. tp_test_ keys access only the isolated sandbox and its synthetic fixtures. The prefix, stored environment and workspace binding must agree.
Grant only the scopes an integration needs. A resource’s write scope grants read access for that same resource only; it does not grant unrelated resource access.
API access requires the organization’s entitlement and administrative enablement. Support sessions cannot manage customer credentials. API keys are server-to-server credentials, not browser credentials; /v1 provides no browser CORS access.
Responses carry x-request-id; error bodies also include request_id. Retain the ID when contacting support. List endpoints use cursor pagination; cursors are opaque and bound to the exact query that created them. Follow pagination.next_cursor until it is null, without changing filters or sort.
Rate-limit failures return HTTP 429. Honor retry-after and the documented rate-limit headers rather than blindly retrying.
An account is the customer organization. Each API key is bound to one workspace; GET /v1/account reports only that bound workspace and environment. Resource IDs are UUIDs, not names. Foreign workspace IDs return not-found responses rather than revealing another customer’s data.
Money values are decimal strings with exactly two fractional digits, such as "1250.00", not JSON numbers or integer minor units. Timestamps use RFC 3339 UTC with a Z suffix; date-only fields use YYYY-MM-DD and month fields use YYYY-MM. Check the generated schema for the exact field format.
A single-resource response is {"data": ...}; lists include data and pagination. On an error, inspect error.code and retain request_id. HTTP 401 indicates key authentication failure; HTTP 403 may indicate missing API enablement or insufficient scopes. HTTP 400/422 indicate request validation issues. Do not retry unchanged invalid inputs.
Create ordinary customer-owned HTTPS endpoints from Settings → Developers. TenantPoint validates destinations server-side and delivers an immutable event body. Human-managed endpoints use HMAC-SHA256; their secret is revealed once on creation or rotation and must be retained in the receiver’s secret manager.
For a human-managed endpoint, verify the HMAC over the timestamp, a period and the exact raw request bytes before parsing JSON. Reject signatures outside the five-minute window. Do not stringify a parsed payload to recreate the signed body.
Transient delivery failures retry with bounded backoff. Explicit replay is available for delivered or dead human-managed deliveries. It queues another delivery attempt for the same immutable event; receivers must deduplicate by event ID.
Zapier integration-owned subscriptions use ES256/P-256 with a public key ring, not a symmetric webhook secret. The integration verifies raw body, timestamp, event ID, subscription ID, signing key ID and environment. Private signing keys stay with TenantPoint.
Integration-owned endpoints are labelled as managed. Their receiver URLs are withheld, and ordinary human endpoint controls cannot rotate, disable or replay them. Their owning integration uses the canonical subscription lifecycle instead.
Select only the events your receiver needs:
vendor.createdvendor.updatedwork_order.createdwork_order.updatedwork_order.note.createdFirst create the test endpoint and confirm your receiver is ready, then make one approved synthetic vendor, work-order or note change through the supported API. Normal domain processing produces the event and webhook delivery; do not fabricate payloads or copy live records. Review Delivery History and validate the signed event before treating HTTP receipt as a successful integration. SSRF and DNS checks remain enforced server-side.
The sandbox is a separate test workspace with canonical synthetic data, not a clone of live records or a normal operational workspace. Create and reset operations derive the organization from the authenticated session.
Reset replaces synthetic business rows and stale idempotency responses. It preserves the sandbox workspace identity, API keys, webhook configuration, event snapshots and delivery history, without emitting a bootstrap event flood. Existing test keys remain bound to the same sandbox. Test writes suppress customer notifications and provider operations; test webhook dispatch remains intentional.
This reference is rendered from the same current OpenAPI source as the OpenAPI 3.1 download. It covers the implemented /v1 operations, required scopes, parameters, request bodies and response codes. Contract version: 1.0.0-alpha.
The Postman collection ships with empty baseUrl and apiKey variables, and both allowRequests and allowMutations set to false. Use a current Postman client supporting pm.execution.skipRequest(). Configure an approved HTTPS origin without /v1, supply the key through a local secret/vault mechanism, and obtain separate approval before enabling reads or mutations. Never run the entire collection blindly or save populated secrets in an exported collection.
GET /v1/accountGet accountIdentity + capability introspection for the authenticated key's workspace: the account (organization), its workspaces, and capabilities. Requires a valid bearer API key and is authorized for the key's workspace; no resource scope is needed (identity endpoint).
Required scope: valid API key
AccountEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/propertiesList propertiesWorkspace-scoped, cursor-paged property list (read-only). Filters: q (substring on name/address). Sort name|created_at (default name asc). Cursor keyset (sort, id). Scope: `properties:read`.
Required scope: properties:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
q | query | No | Case-insensitive substring match on name or address. |
sort | query | No | Sort column (default name). Unsupported sorts are rejected (invalid_enum_value). |
order | query | No | asc or desc. Only valid together with sort. |
PropertiesListEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/properties/{id}Get a propertyReturns one property by id. An id for another workspace returns 404 resource_not_found -- never 403 and never the row. Scope: `properties:read`.
Required scope: properties:read
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Properties id (uuid). |
PropertyEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/vendorsList vendorsWorkspace-scoped, cursor-paged vendor list. Filters: is_active, category (comma-separated, exact match as stored), q (substring on name/email/notes). Sort name|created_at (default name asc). Scope: `vendors:read`.
Required scope: vendors:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
is_active | query | No | true = active vendors only; false = retired vendors only. Absent = all. |
category | query | No | Comma-separated category values, exact match as stored (no case folding). |
q | query | No | Case-insensitive substring match on name, email, or notes. |
sort | query | No | Sort column (default name). Unsupported sorts are rejected (invalid_enum_value). |
order | query | No | asc or desc. Only valid together with sort. |
VendorsListEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPOST /v1/vendorsCreate a vendorCreates a vendor in the authenticated key's workspace. The body is strict: only the fields in CreateVendorInput are accepted. `external_references` is response-only in Phase 2E and is rejected on write. Scope: `vendors:write`. A required Idempotency-Key makes retries safe after a completed response; an equivalent request still in progress returns 409 and must be retried.
Required scope: vendors:write
| Name | Location | Required | Description |
|---|---|---|---|
Idempotency-Key | header | Yes | Required unique token for this create request. It must be 1-255 ASCII token characters (A-Z, a-z, 0-9, -, _, ., :, /, +) with no spaces. Reuse with an equivalent body replays the completed response; reuse with a different body, or while the original request is in progress, returns 409. |
JSON request body: CreateVendorInput (required)
VendorEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/vendors/{id}Get a vendorReturns one vendor by id. An id for another workspace returns 404 resource_not_found -- never 403 and never the row. Scope: `vendors:read`.
Required scope: vendors:read
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Vendors id (uuid). |
VendorEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPATCH /v1/vendors/{id}Update a vendorPartially updates a vendor in the authenticated key's workspace. Omitted fields are unchanged; category, email, phone, and notes accept null to clear their values. An empty object has no change to apply and returns `400 invalid_parameter`. No DELETE endpoint exists; set `is_active` to false to retire a vendor. Scope: `vendors:write`.
Required scope: vendors:write
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Resource id (uuid). |
JSON request body: UpdateVendorInput (required)
VendorEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/work-ordersList work ordersWorkspace-scoped, cursor-paged work order list. Filters: property_id (verified to the workspace), status, priority (comma-separated), created_* and updated_* timestamp ranges. Sort created_at (default desc). Other catalog filters (tenant_id, category_id, hold_reason, is_emergency, q) are deferred to a later phase. Scope: `work_orders:read`.
Required scope: work_orders:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
property_id | query | No | Only work orders for this workspace property. A property_id outside your workspace returns 404 resource_not_found. |
status | query | No | Comma-separated statuses. |
priority | query | No | Comma-separated priorities. |
created_after | query | No | Only rows created at or after this instant. |
created_before | query | No | Only rows created at or before this instant. |
updated_after | query | No | Only rows updated at or after this instant. |
updated_before | query | No | Only rows updated at or before this instant. |
sort | query | No | Sort column (default created_at). Unsupported sorts are rejected (invalid_enum_value). |
order | query | No | asc or desc. Only valid together with sort. |
WorkOrdersListEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPOST /v1/work-ordersCreate a work orderCreates a work order in the authenticated key's workspace. The referenced property and category must be usable within that workspace. The body is strict: only CreateWorkOrderInput fields are accepted, and `external_references` is response-only in Phase 2E. Scope: `work_orders:write`. A required Idempotency-Key makes retries safe after a completed response; an equivalent request still in progress returns 409 and must be retried.
Required scope: work_orders:write
| Name | Location | Required | Description |
|---|---|---|---|
Idempotency-Key | header | Yes | Required unique token for this create request. It must be 1-255 ASCII token characters (A-Z, a-z, 0-9, -, _, ., :, /, +) with no spaces. Reuse with an equivalent body replays the completed response; reuse with a different body, or while the original request is in progress, returns 409. |
JSON request body: CreateWorkOrderInput (required)
WorkOrderEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/work-orders/{id}Get a work orderReturns one work order by id (full state-machine state). An id for another workspace returns 404 resource_not_found -- never 403 and never the row. Scope: `work_orders:read`.
Required scope: work_orders:read
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Work Orders id (uuid). |
WorkOrderEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPATCH /v1/work-orders/{id}Update a work orderPartially updates a work order in the authenticated key's workspace. `hold_reason` and `reopen_reason` are permitted only when the request also supplies `status`; status transitions are checked against the work-order state machine. An empty object has no change to apply and returns `400 invalid_parameter`. Scope: `work_orders:write`.
Required scope: work_orders:write
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Resource id (uuid). |
JSON request body: UpdateWorkOrderInput (required)
WorkOrderEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/documentsList documentsWorkspace-scoped, cursor-paged document list (read-only). Filters: property_id (verified to the workspace), kind (comma-separated, exact match), extraction_status (comma-separated), created_* timestamp range, q (substring on filename). Sort created_at (default desc). Scope: `documents:read`.
Required scope: documents:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
property_id | query | No | Only documents for this workspace property. A property_id outside your workspace returns 404 resource_not_found. |
kind | query | No | Comma-separated document kind values, exact match as stored (no case folding). |
extraction_status | query | No | Comma-separated extraction statuses. |
created_after | query | No | Only rows created at or after this instant. |
created_before | query | No | Only rows created at or before this instant. |
q | query | No | Case-insensitive substring match on filename. |
sort | query | No | Sort column (default created_at). Unsupported sorts are rejected (invalid_enum_value). |
order | query | No | asc or desc. Only valid together with sort. |
DocumentsListEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/documents/{id}Get a documentReturns one document by id. An id for another workspace returns 404 resource_not_found -- never 403 and never the row. Scope: `documents:read`.
Required scope: documents:read
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Documents id (uuid). |
DocumentEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/transactionsList transactionsWorkspace-scoped, cursor-paged bank transaction list (read-only). Filters: property_id (verified), status, allocation_type, source (comma-separated), date_* and created_* ranges, q (substring on description/merchant_name). Sort date|created_at (default date desc). Scope: `transactions:read`.
Required scope: transactions:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
property_id | query | No | Only transactions for this workspace property (as allocated). A property_id outside your workspace returns 404 resource_not_found. |
status | query | No | Comma-separated statuses. |
allocation_type | query | No | Comma-separated allocation types. |
source | query | No | Comma-separated sources. |
date_after | query | No | Only rows with transaction date at or after this day. |
date_before | query | No | Only rows with transaction date at or before this day. |
created_after | query | No | Only rows created at or after this instant. |
created_before | query | No | Only rows created at or before this instant. |
q | query | No | Case-insensitive substring match on description or merchant_name. |
sort | query | No | Sort column (default date). Unsupported sorts are rejected (invalid_enum_value). |
order | query | No | asc or desc. Only valid together with sort. |
TransactionsListEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/transactions/{id}Get a transactionReturns one bank transaction by id. An id for another workspace returns 404 resource_not_found -- never 403 and never the row. Scope: `transactions:read`.
Required scope: transactions:read
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Transactions id (uuid). |
TransactionEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/paymentsList paymentsWorkspace-scoped, cursor-paged rent payment list (read-only). Filters: property_id, tenant_id (both verified to the workspace), month (comma-separated YYYY-MM), status, method (comma-separated), received_* date range. Sort received_date|month|created_at (default created_at desc). Scope: `payments:read`.
Required scope: payments:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
property_id | query | No | Only payments for this workspace property. A property_id outside your workspace returns 404 resource_not_found. |
tenant_id | query | No | Only payments from this workspace tenant. A tenant_id outside your workspace returns 404 resource_not_found. |
month | query | No | Comma-separated YYYY-MM billing months (e.g. month=2026-09,2026-10). |
status | query | No | Comma-separated statuses. |
method | query | No | Comma-separated payment method values, exact match as stored (no case folding). |
received_after | query | No | Only rows received at or after this day. |
received_before | query | No | Only rows received at or before this day. |
sort | query | No | Sort column (default created_at). Unsupported sorts are rejected (invalid_enum_value). |
order | query | No | asc or desc. Only valid together with sort. |
PaymentsListEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/payments/{id}Get a paymentReturns one rent payment by id. An id for another workspace returns 404 resource_not_found -- never 403 and never the row. Scope: `payments:read`.
Required scope: payments:read
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Payments id (uuid). |
PaymentEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPOST /v1/work-orders/{id}/notesAdd a work-order noteAppends a note to a work order in the authenticated key's workspace. Notes are append-only in v1; visibility is `internal` by default and may be `internal` or `tenant`. This endpoint does not implement idempotency in Phase 2E. Scope: `work_orders:write`.
Required scope: work_orders:write
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | Resource id (uuid). |
JSON request body: CreateWorkOrderNoteInput (required)
WorkOrderNoteEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyGET /v1/work-order-categoriesList work-order categoriesList work-order categories
Required scope: work_orders:read
| Name | Location | Required | Description |
|---|---|---|---|
limit | query | No | Number of rows to return (max 100; default 50). Values above the cap or non-numeric strings are rejected (invalid_parameter). |
cursor | query | No | Opaque cursor from the previous response's pagination.next_cursor. Signed to THIS exact query (filters + sort + order); reusing one from any other query returns invalid_cursor. |
WorkOrderCategoriesEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPOST /v1/webhook-subscriptionsCreate an API-key-owned Zapier subscriptionAlso requires vendors:read or work_orders:read for the selected event. Caller supplies no ownership or secret fields. TenantPoint signs delivery with its dedicated ES256 key; the response contains only the non-secret signing key id. Repeated subscription identity returns 409. No generic endpoint management is exposed.
Required scope: webhooks:write
JSON request body: CreateWebhookSubscriptionInput (required)
CreatedWebhookSubscriptionEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyPOST /v1/webhook-subscriptions/{id}/disableDisable an owned Zapier subscriptionSame owning API key required, even within the same workspace. Foreign IDs return 404. Repeated disable succeeds without deleting history. In-flight requests cannot be recalled.
Required scope: webhooks:write
| Name | Location | Required | Description |
|---|---|---|---|
id | path | Yes | {"type":"string","format":"uuid"} |
WebhookSubscriptionEnvelopeErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyErrorBodyExpand a schema for its exact field types, required fields, enums and validation constraints. JSON Schema references point to other named schemas in this section.
WorkOrderCategory{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"name": {
"type": "string"
},
"default_priority": {
"type": "string",
"enum": [
"low",
"normal",
"high",
"emergency"
]
},
"is_emergency_default": {
"type": "boolean"
}
},
"required": [
"id",
"name",
"default_priority",
"is_emergency_default"
],
"additionalProperties": false
}CreateWebhookSubscriptionInput{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"integration": {
"type": "string",
"const": "zapier"
},
"subscription_identity": {
"type": "string",
"minLength": 1,
"maxLength": 200,
"pattern": "^[A-Za-z0-9._:-]+$"
},
"target_url": {
"type": "string",
"minLength": 9,
"maxLength": 2048
},
"event_type": {
"type": "string",
"enum": [
"vendor.created",
"vendor.updated",
"work_order.created",
"work_order.updated",
"work_order.note.created"
]
}
},
"required": [
"integration",
"subscription_identity",
"target_url",
"event_type"
],
"additionalProperties": false
}CreatedWebhookSubscription{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"event_type": {
"type": "string",
"enum": [
"vendor.created",
"vendor.updated",
"work_order.created",
"work_order.updated",
"work_order.note.created"
]
},
"status": {
"type": "string",
"enum": [
"active",
"disabled"
]
},
"environment": {
"type": "string",
"enum": [
"live",
"test"
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"signing_key_id": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{1,64}$"
}
},
"required": [
"id",
"event_type",
"status",
"environment",
"created_at",
"signing_key_id"
],
"additionalProperties": false
}WebhookSubscription{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"event_type": {
"type": "string",
"enum": [
"vendor.created",
"vendor.updated",
"work_order.created",
"work_order.updated",
"work_order.note.created"
]
},
"status": {
"type": "string",
"enum": [
"active",
"disabled"
]
},
"environment": {
"type": "string",
"enum": [
"live",
"test"
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"event_type",
"status",
"environment",
"created_at"
],
"additionalProperties": false
}Account{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"environment": {
"type": "string",
"enum": [
"live",
"test"
]
},
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"name": {
"type": "string"
},
"created_at": {
"type": "string"
},
"workspaces": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"name": {
"type": "string"
},
"created_at": {
"type": "string"
}
},
"required": [
"id",
"name",
"created_at"
],
"additionalProperties": false
}
},
"capabilities": {
"type": "object",
"properties": {
"api_enabled": {
"type": "boolean"
}
},
"required": [
"api_enabled"
],
"additionalProperties": false
}
},
"required": [
"environment",
"id",
"name",
"created_at",
"workspaces",
"capabilities"
],
"additionalProperties": false,
"description": "An account groups a customer's workspaces."
}WorkspaceSummary{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"name": {
"type": "string"
},
"created_at": {
"type": "string"
}
},
"required": [
"id",
"name",
"created_at"
],
"additionalProperties": false,
"description": "Workspace summary inside an Account"
}Property{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"name": {
"type": "string"
},
"address": {
"type": "string"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
}
},
"required": [
"id",
"name",
"address",
"created_at",
"updated_at"
],
"additionalProperties": false,
"description": "A rental property (read-only in V1)"
}Vendor{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"category": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"is_active": {
"type": "boolean"
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"external_references": {
"type": "array",
"items": {
"type": "object",
"properties": {
"namespace": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{1,63}$"
},
"external_id": {
"type": "string",
"pattern": "^[\\x21-\\x7e][\\x20-\\x7e]{0,254}$"
}
},
"required": [
"namespace",
"external_id"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"name",
"category",
"email",
"phone",
"notes",
"is_active",
"created_at",
"updated_at",
"external_references"
],
"additionalProperties": false,
"description": "A vendor (read/create/update, retire-by-flag)"
}CreateVendorInput{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"category": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"is_active": {
"type": "boolean"
}
},
"required": [
"name"
],
"additionalProperties": false
}UpdateVendorInput{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"category": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"is_active": {
"type": "boolean"
}
},
"additionalProperties": false
}WorkOrder{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"property_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"tenant_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"category_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"category_name": {
"type": "string"
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"description": {
"type": "string"
},
"status": {
"type": "string",
"enum": [
"submitted",
"triaged",
"assigned",
"scheduled",
"in_progress",
"on_hold",
"pending_tenant",
"pending_approval",
"completed",
"closed",
"cancelled"
]
},
"priority": {
"type": "string",
"enum": [
"low",
"normal",
"high",
"emergency"
]
},
"hold_reason": {
"anyOf": [
{
"type": "string",
"enum": [
"awaiting_tenant",
"awaiting_vendor",
"awaiting_parts",
"awaiting_approval",
"other"
]
},
{
"type": "null"
}
]
},
"is_emergency": {
"type": "boolean"
},
"access_instructions": {
"type": [
"string",
"null"
]
},
"parent_work_order_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"duplicate_of_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"vendor_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"submitted_by_type": {
"type": "string",
"enum": [
"tenant",
"manager",
"system"
]
},
"created_at": {
"type": "string"
},
"updated_at": {
"type": "string"
},
"closed_at": {
"type": [
"string",
"null"
]
},
"external_references": {
"type": "array",
"items": {
"type": "object",
"properties": {
"namespace": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{1,63}$"
},
"external_id": {
"type": "string",
"pattern": "^[\\x21-\\x7e][\\x20-\\x7e]{0,254}$"
}
},
"required": [
"namespace",
"external_id"
],
"additionalProperties": false
}
}
},
"required": [
"id",
"property_id",
"tenant_id",
"category_id",
"category_name",
"title",
"description",
"status",
"priority",
"hold_reason",
"is_emergency",
"access_instructions",
"parent_work_order_id",
"duplicate_of_id",
"vendor_id",
"submitted_by_type",
"created_at",
"updated_at",
"closed_at",
"external_references"
],
"additionalProperties": false,
"description": "A work order in its full state-machine state"
}CreateWorkOrderInput{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"property_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"category_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"tenant_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"description": {
"type": "string"
},
"priority": {
"type": "string",
"enum": [
"low",
"normal",
"high",
"emergency"
]
},
"is_emergency": {
"type": "boolean"
},
"access_instructions": {
"type": [
"string",
"null"
]
}
},
"required": [
"property_id",
"title",
"category_id"
],
"additionalProperties": false
}UpdateWorkOrderInput{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"description": {
"type": "string"
},
"access_instructions": {
"type": [
"string",
"null"
]
},
"priority": {
"type": "string",
"enum": [
"low",
"normal",
"high",
"emergency"
]
},
"is_emergency": {
"type": "boolean"
},
"status": {
"type": "string",
"enum": [
"submitted",
"triaged",
"assigned",
"scheduled",
"in_progress",
"on_hold",
"pending_tenant",
"pending_approval",
"completed",
"closed",
"cancelled"
]
},
"hold_reason": {
"anyOf": [
{
"type": "string",
"enum": [
"awaiting_tenant",
"awaiting_vendor",
"awaiting_parts",
"awaiting_approval",
"other"
]
},
{
"type": "null"
}
]
},
"reopen_reason": {
"type": "string"
},
"parent_work_order_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false
}WorkOrderNote{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"work_order_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"body": {
"type": "string",
"minLength": 1,
"maxLength": 4000
},
"visibility": {
"type": "string",
"enum": [
"internal",
"tenant",
"vendor"
]
},
"author_type": {
"type": "string",
"enum": [
"manager",
"tenant",
"vendor",
"system"
]
},
"created_at": {
"type": "string"
}
},
"required": [
"id",
"work_order_id",
"body",
"visibility",
"author_type",
"created_at"
],
"additionalProperties": false
}CreateWorkOrderNoteInput{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"body": {
"type": "string",
"minLength": 1,
"maxLength": 4000
},
"visibility": {
"type": "string",
"enum": [
"internal",
"tenant"
]
}
},
"required": [
"body"
],
"additionalProperties": false
}Document{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"property_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"filename": {
"type": "string"
},
"kind": {
"type": "string"
},
"content_type": {
"type": "string"
},
"size": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"status": {
"type": "string"
},
"extraction_status": {
"type": "string",
"enum": [
"pending",
"processing",
"review",
"verified",
"failed"
]
},
"verified_at": {
"type": [
"string",
"null"
]
},
"created_at": {
"type": "string"
}
},
"required": [
"id",
"property_id",
"filename",
"kind",
"content_type",
"size",
"status",
"extraction_status",
"verified_at",
"created_at"
],
"additionalProperties": false,
"description": "An uploaded document (read-only in V1)"
}Transaction{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"property_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"date": {
"type": "string"
},
"description": {
"type": "string"
},
"amount": {
"type": "string",
"pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{2})$"
},
"category": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"review",
"reconciled",
"ignored"
]
},
"allocation_type": {
"type": "string",
"enum": [
"unassigned",
"house",
"tenant",
"selected",
"all"
]
},
"source": {
"type": "string",
"enum": [
"csv_import",
"plaid_sync"
]
},
"merchant_name": {
"type": [
"string",
"null"
]
},
"pending": {
"type": "boolean"
},
"work_order_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string"
}
},
"required": [
"id",
"property_id",
"date",
"description",
"amount",
"category",
"status",
"allocation_type",
"source",
"merchant_name",
"pending",
"work_order_id",
"created_at"
],
"additionalProperties": false,
"description": "A bank transaction (read-only in V1)"
}Payment{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"property_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"tenant_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
"month": {
"type": "string",
"pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
},
"amount": {
"type": "string",
"pattern": "^-?(0|[1-9][0-9]*)(\\.[0-9]{2})$"
},
"received_date": {
"type": "string"
},
"method": {
"type": "string"
},
"reference": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"confirmed",
"returned"
]
},
"bank_transaction_id": {
"anyOf": [
{
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string"
}
},
"required": [
"id",
"property_id",
"tenant_id",
"month",
"amount",
"received_date",
"method",
"reference",
"status",
"bank_transaction_id",
"created_at"
],
"additionalProperties": false,
"description": "An operational rent payment (read-only in V1)"
}Pagination{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"has_more",
"next_cursor"
],
"additionalProperties": false,
"description": "Cursor pagination block"
}ErrorBody{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"error": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"authentication_error",
"permission_error",
"not_found_error",
"validation_error",
"conflict_error",
"rate_limit_error",
"internal_error"
]
},
"code": {
"type": "string"
},
"message": {
"type": "string"
},
"param": {
"type": "string"
},
"request_id": {
"type": "string",
"pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
}
},
"required": [
"type",
"code",
"message",
"request_id"
],
"additionalProperties": false
}
},
"required": [
"error"
],
"additionalProperties": false,
"description": "The single error envelope"
}AccountEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/Account"
}
}
}WorkOrderCategoriesEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WorkOrderCategory"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}CreatedWebhookSubscriptionEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/CreatedWebhookSubscription"
}
}
}WebhookSubscriptionEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/WebhookSubscription"
}
}
}WorkOrderNoteEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/WorkOrderNote"
}
}
}PropertiesListEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Property"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}PropertyEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/Property"
}
}
}VendorsListEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Vendor"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}VendorEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/Vendor"
}
}
}WorkOrdersListEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WorkOrder"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}WorkOrderEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/WorkOrder"
}
}
}DocumentsListEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Document"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}DocumentEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/Document"
}
}
}TransactionsListEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Transaction"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}TransactionEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/Transaction"
}
}
}PaymentsListEnvelope{
"type": "object",
"required": [
"data",
"pagination"
],
"properties": {
"data": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Payment"
}
},
"pagination": {
"$ref": "#/components/schemas/Pagination"
}
}
}PaymentEnvelope{
"type": "object",
"required": [
"data"
],
"properties": {
"data": {
"$ref": "#/components/schemas/Payment"
}
}
}TenantPoint versions the public API in the URL. Additive changes can arrive in /v1; breaking changes require a new major version. Create operations that require an Idempotency-Key safely replay the completed equivalent request and reject a conflicting body.
Webhook payloads are versioned independently. Build receivers to reject unsupported schema versions safely and to tolerate additive fields.
The current contract includes workspace-scoped API-key authentication, cursor-paged reads, vendor and work-order create/update, append-only work-order notes, account capabilities, work-order categories and API-key-owned Zapier subscriptions.
The Developer Platform adds session-bound management of API keys, human webhooks and synthetic sandbox lifecycle without changing the public /v1 contract. Zapier subscriptions remain integration-owned and use ES256 public-key verification.
Additive fields, optional parameters and endpoints may be added to /v1. Removing or renaming a documented field, changing its meaning or type, or changing documented validation, authentication or scoping behavior requires a new major API version. Deprecations will be documented before retirement; no fixed sunset window is currently promised.
For troubleshooting, retain the request ID or delivery ID, endpoint environment and safe error code, then use the TenantPoint contact page. Never send API keys, signing secrets, private keys or webhook payloads containing customer data to support channels.
Common patterns include syncing vendors to a CRM, creating work orders from a field-service tool, forwarding signed events to an ERP, and using the private Zapier integration for no-code workflows. For chat notifications, a trusted server-side receiver can validate an event before forwarding a sanitized message to Slack or Teams. These are integration patterns, not claims of built-in accounting or messaging actions.