{"openapi":"3.0.3","info":{"title":"Perch API","description":"REST API for Perch — AI-powered tax intelligence for short-term rental operators.\n\nAuthenticate with an API key in the `Authorization: Bearer pk_...` header.\nGenerate keys from the Perch app under **API** in the nav bar.","version":"1.0.0","contact":{"name":"Perch Support","email":"peter@getperch.ai"},"termsOfService":"https://www.tallyfor.com/legal/privacy-policy"},"servers":[{"url":"https://api.getperch.ai","description":"Production"},{"url":"https://perch-api-561136038046.us-central1.run.app","description":"Staging"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"apiKey","name":"Authorization","in":"header","description":"API key prefixed with 'Bearer '. Example: `Bearer pk_user_abc123...`"}},"schemas":{"Property":{"type":"object","properties":{"active?":{"type":"boolean"},"address":{"type":"string"},"name":{"type":"string"},"city":{"type":"string"},"property-type":{"type":"string","enum":["single-family","condo","townhouse","multi-family"]},"state":{"type":"string"},"id":{"type":"string"},"listing-channels":{"type":"array","items":{"type":"string"}},"rental-type":{"type":"string","enum":["short-term","long-term"]},"zip-code":{"type":"string"},"created-at":{"type":"string","format":"date-time"}}},"Transaction":{"type":"object","properties":{"description":{"type":"string"},"amount":{"type":"number"},"date":{"type":"string","format":"date"},"source":{"type":"string","enum":["plaid","stessa","manual"]},"property-id":{"type":"string"},"perch-category":{"type":"string","description":"Account code (401, 601, etc.)"},"id":{"type":"string"},"reconciled?":{"type":"boolean"},"created-at":{"type":"string","format":"date-time"}}},"Booking":{"type":"object","properties":{"net-revenue":{"type":"number"},"channel":{"type":"string","enum":["airbnb","vrbo","booking.com","direct","other"]},"property-id":{"type":"string"},"guest-name":{"type":"string"},"status":{"type":"string"},"id":{"type":"string"},"check-in":{"type":"string","format":"date"},"gross-revenue":{"type":"number"},"check-out":{"type":"string","format":"date"}}},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string","format":"uri"},"enabled":{"type":"boolean"},"events":{"type":"array","items":{"type":"string"}},"signing-secret":{"type":"string","description":"HMAC signing secret (shown once on creation)"}}},"CategorizedRule":{"type":"object","properties":{"id":{"type":"string"},"pattern":{"type":"string"},"match-type":{"type":"string","enum":["contains","exact","starts-with"]},"perch-category":{"type":"string"}}},"ParticipationHours":{"type":"object","properties":{"id":{"type":"string"},"property-id":{"type":"string"},"date":{"type":"string","format":"date"},"hours":{"type":"number"},"activity-type":{"type":"string","enum":["maintenance","guest-communication","cleaning","management","marketing","accounting","other"]},"description":{"type":"string"}}},"PaginatedResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"meta":{"type":"object","properties":{"total":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"}}}}},"Error":{"type":"object","properties":{"error":{"type":"string"}}}}},"paths":{"/v1/transactions/{id}":{"get":{"summary":"Get transaction","tags":["Transactions"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}},"put":{"summary":"Update transaction","tags":["Transactions"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Updated"}}},"delete":{"summary":"Delete transaction","tags":["Transactions"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/v1/keys/{id}":{"delete":{"summary":"Revoke API key","tags":["API Keys"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked"}}}},"/v1/properties/{id}":{"get":{"summary":"Get property","tags":["Properties"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"},"404":{"description":"Not found"}}},"put":{"summary":"Update property","tags":["Properties"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Property"}}}},"responses":{"200":{"description":"Updated"}}},"delete":{"summary":"Delete property","tags":["Properties"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/v1/hours":{"get":{"summary":"List participation hours","tags":["Participation Hours"],"responses":{"200":{"description":"Success"}}},"post":{"summary":"Log hours","tags":["Participation Hours"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipationHours"}}}},"responses":{"201":{"description":"Created"}}}},"/v1/keys":{"get":{"summary":"List API keys","tags":["API Keys"],"responses":{"200":{"description":"Success"}}},"post":{"summary":"Generate API key","tags":["API Keys"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["user","cpa"]}}}}}},"responses":{"201":{"description":"Key created — plaintext key shown once"}}}},"/v1/bookings/{id}":{"get":{"summary":"Get booking","tags":["Bookings"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success"}}},"put":{"summary":"Update booking","tags":["Bookings"],"responses":{"200":{"description":"Updated"}}},"delete":{"summary":"Delete booking","tags":["Bookings"],"responses":{"200":{"description":"Deleted"}}}},"/v1/bookings":{"get":{"summary":"List bookings","tags":["Bookings"],"responses":{"200":{"description":"Success"}}},"post":{"summary":"Create booking","tags":["Bookings"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Booking"}}}},"responses":{"201":{"description":"Created"}}}},"/v1/properties":{"get":{"summary":"List properties","tags":["Properties"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"owner_uid","in":"query","schema":{"type":"string"},"description":"CPA keys: specify client UID"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse"}}}}}},"post":{"summary":"Create property","tags":["Properties"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Property"}}}},"responses":{"201":{"description":"Created"}}}},"/v1/rules":{"get":{"summary":"List categorization rules","tags":["Rules"],"responses":{"200":{"description":"Success"}}},"post":{"summary":"Create rule","tags":["Rules"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategorizedRule"}}}},"responses":{"201":{"description":"Created"}}}},"/v1/webhooks":{"get":{"summary":"List webhooks","tags":["Webhooks"],"responses":{"200":{"description":"Success"}}},"post":{"summary":"Create webhook","tags":["Webhooks"],"description":"Available events: property.created, property.updated, property.deleted, transaction.created, transaction.updated, transaction.categorized, transaction.deleted, booking.created, booking.updated, booking.deleted, bank.synced, report.generated, rule.created, rule.deleted, hours.logged","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"responses":{"201":{"description":"Created — signing secret included (shown once)"}}}},"/v1/webhooks/{id}":{"delete":{"summary":"Delete webhook","tags":["Webhooks"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"}}}},"/v1/transactions":{"get":{"summary":"List transactions","tags":["Transactions"],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"property-id","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","schema":{"type":"string"},"description":"Perch account code (401, 601, etc.)"},{"name":"from-date","in":"query","schema":{"type":"string","format":"date"}},{"name":"to-date","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Success"}}},"post":{"summary":"Create transaction","tags":["Transactions"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transaction"}}}},"responses":{"201":{"description":"Created"}}}},"/v1/webhooks/{id}/test":{"post":{"summary":"Test webhook","tags":["Webhooks"],"description":"Send a test event to verify webhook delivery","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery result"}}}},"/v1/bank-accounts":{"get":{"summary":"List bank accounts (read-only)","tags":["Bank Accounts"],"responses":{"200":{"description":"Success"}}}},"/v1/reports/portfolio":{"get":{"summary":"Get portfolio summary","tags":["Reports"],"responses":{"200":{"description":"Success"}}}},"/v1/rules/{id}":{"get":{"summary":"Get rule","tags":["Rules"],"responses":{"200":{"description":"Success"}}},"delete":{"summary":"Delete rule","tags":["Rules"],"responses":{"200":{"description":"Deleted"}}}}}}