L’interface est localisée ; les présentations et documents des Skills sont traduits automatiquement par IA dans votre langue. Le code, les commandes, chemins et termes techniques restent en version originale, et le document de l’auteur fait foi.
Explorer les Skills
Données et recherche · SKILL.md

appfolio-core-workflow-a

appfolio-core-workflow-a

Build property management dashboard with AppFolio API data. Trigger: "appfolio property dashboard".

Independent GitHub snapshot · Automated classification · Original documentation governs

Documentation de la Skill

GitHub

name: appfolio-core-workflow-a description: 'Build property management dashboard with AppFolio API data.

Trigger: "appfolio property dashboard".

' allowed-tools: Read, Write, Edit, Bash(npm:), Bash(curl:), Grep version: 1.5.0 license: MIT author: Jeremy Longshore jeremy@intentsolutions.io tags:

  • saas
  • property-management
  • appfolio
  • real-estate compatibility: Designed for Claude Code

AppFolio — Property & Tenant Management

Overview

Primary workflow for AppFolio property management integration. Covers the full property lifecycle: creating and updating property records, managing tenant profiles and lease agreements, and querying occupancy data. Uses the AppFolio Stack API with OAuth 2.0 client credentials for server-to-server access. All endpoints return JSON and support pagination via cursor parameters for large portfolios.

Prerequisites

  • A current AppFolio partner/API contract that confirms the assigned portfolio base URL, authentication method, approved scopes, and write capabilities; do not infer these from a tutorial or another portfolio.
  • A separate sandbox with disposable properties, units, and synthetic tenant records, plus a credential owner and an approved request budget.
  • Idempotency keys and an operator-approved rollback/reconciliation process for property, tenant, and lease writes, which can create real legal and billing consequences.

Instructions

  1. Confirm the provider-issued base URL and authentication flow for the target portfolio before copying any client configuration into an environment.
  2. Exercise the create/update path only with sandbox synthetic fixtures and idempotency keys; retrieve canonical records before retrying an uncertain write.
  3. Validate ownership, lease dates, and unit availability before creating a lease, and emit only record IDs and redacted status evidence.
  4. Promote a write-capable flow only after a staged rehearsal proves rollback, reconciliation, and the least-privilege scope boundary.

Step 1: Authenticate and Initialize Client

const token = await fetch('https://api.appfolio.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: process.env.APPFOLIO_CLIENT_ID!,
    client_secret: process.env.APPFOLIO_CLIENT_SECRET!,
    scope: 'properties tenants leases',
  }),
}).then(r => r.json());
const headers = { Authorization: `Bearer ${token.access_token}`, 'Content-Type': 'application/json' };

Step 2: Create or Update a Property

const property = await fetch('https://api.appfolio.com/v1/properties', {
  method: 'POST', headers,
  body: JSON.stringify({
    name: 'Sunrise Apartments',
    address: { street: '100 Main St', city: 'Austin', state: 'TX', zip: '78701' },
    type: 'residential',
    units: [
      { number: '101', bedrooms: 2, bathrooms: 1, rent: 1450 },
      { number: '102', bedrooms: 1, bathrooms: 1, rent: 1100 },
    ],
  }),
}).then(r => r.json());
console.log(`Property created: ${property.id}`);

Step 3: Add a Tenant and Lease

const tenant = await fetch('https://api.appfolio.com/v1/tenants', {
  method: 'POST', headers,
  body: JSON.stringify({
    first_name: 'Test', last_name: 'Tenant',
    email: 'test-tenant@example.invalid', phone: '555-0100',
  }),
}).then(r => r.json());

await fetch('https://api.appfolio.com/v1/leases', {
  method: 'POST', headers,
  body: JSON.stringify({
    property_id: property.id, unit_number: '101',
    tenant_id: tenant.id, start_date: '2026-05-01', end_date: '2027-04-30',
    monthly_rent: 1450, security_deposit: 1450,
  }),
}).then(r => r.json());

Step 4: Query Occupancy

const units = await fetch(
  `https://api.appfolio.com/v1/properties/${property.id}/units?status=vacant`,
  { headers },
).then(r => r.json());
console.log(`Vacant units: ${units.data.length} of ${units.meta.total}`);

Error Handling

IssueCauseFix
401 UnauthorizedExpired or invalid tokenRe-authenticate with client credentials
404 Not FoundWrong property/tenant IDVerify resource ID exists before referencing
422 UnprocessableMissing required fieldsCheck errors[] array in response body
409 ConflictDuplicate lease for unitQuery existing leases before creating
429 Too Many RequestsRate limit exceededBack off using Retry-After header value

Output

A successful run creates a property with units, adds a tenant, binds them via a lease, and reports vacancy counts. Console output confirms each resource ID on creation.

Examples

For a lease-creation change, run against a named synthetic sandbox unit and tenant with a stable idempotency key. Read the property and current leases, perform the candidate write once, then read back the resulting lease and record only IDs, dates, and the reconciliation status. Re-run the same request to prove it does not create a second lease. If the provider contract, endpoint, authorization, or prior-write outcome cannot be verified, stop before any write and send the case to the portfolio operator for reconciliation.

Resources

Next Steps

Continue with appfolio-core-workflow-b for maintenance requests and payment tracking.

Skills enregistrées