Worlds / Real estate
AppFolio API
A local AppFolio Property Manager with units, listings, rental applications, leases and work orders. Test the maintenance and leasing agent that triages requests, dispatches vendors and moves applications along.
- Base path
/api/v1- Auth
- HTTP basic with client id and secret, the world key
- Endpoints
- 17
- Status
- Active today
This reference previews the surface the AppFolio world serves in the closed beta. Paths mirror the public AppFolio API; the exact subset is confirmed when your workflow is scoped.
Connect
The run gives your agent these bindings. Keep your SDK; change only where it sends requests.
| binding | meaning |
|---|---|
WORLDS_APPFOLIO_URL | This world's origin followed by /api/v1 |
WORLDS_API_KEY | The world key, accepted wherever AppFolio expects a credential |
WORLDS_WORLD_ID | The isolated world's identity |
const base = process.env.WORLDS_APPFOLIO_URL + "/api/v1";
const auth = "Basic " + Buffer.from(process.env.WORLDS_API_KEY + ":" + process.env.WORLDS_API_KEY).toString("base64");
const res = await fetch(base + "/reports/rent_roll.json", {
method: "POST",
headers: { Authorization: auth, "Content-Type": "application/json" },
body: JSON.stringify({ properties_ids: [], unit_visibility: "active" }),
});
const { results } = await res.json();API reference
Properties
Managed properties.
- GET
/api/v1/propertiesList properties - GET
/api/v1/properties/{id}Get a property - GET
/api/v1/properties/{id}/unitsList units
Fields · 5
id | integer | Property id |
name | string | Property name |
address | object | Address |
property_type | string | Type |
unit_count | integer | Number of units |
Tenants
Residents and lease holders.
- GET
/api/v1/tenantsList tenants - GET
/api/v1/tenants/{id}Get a tenant - POST
/api/v1/tenantsCreate a tenant - PATCH
/api/v1/tenants/{id}Update a tenant
Fields · 6
id | integer | Tenant id |
first_name | string | Given name |
last_name | string | Family name |
email | string | |
unit_id | integer | Unit |
move_in_on | date | Move-in date |
Work orders
Maintenance requests.
- GET
/api/v1/work_ordersList work orders - GET
/api/v1/work_orders/{id}Get a work order - POST
/api/v1/work_ordersCreate a work order - PATCH
/api/v1/work_orders/{id}Update a work order
Fields · 6
id | integer | Work order id |
status | string | New, Assigned, Scheduled, Completed |
priority | string | Priority |
description | string | Problem description |
vendor_id | integer | Assigned vendor |
unit_id | integer | Unit |
Leases
Lease terms and rent.
- GET
/api/v1/leasesList leases - GET
/api/v1/leases/{id}Get a lease - POST
/api/v1/leasesCreate a lease
Fields · 6
id | integer | Lease id |
tenant_ids | integer[] | Tenants on the lease |
start_on | date | Lease start |
end_on | date | Lease end |
rent | number | Monthly rent |
status | string | Active, Past, Future |
Reports
Rent roll, delinquency and ledgers.
- POST
/api/v1/reports/rent_roll.jsonRun the rent roll - POST
/api/v1/reports/delinquency.jsonRun the delinquency report - POST
/api/v1/reports/tenant_ledger.jsonRun the tenant ledger
Fields · 3
results | object[] | Report rows |
next_page_url | string | Next page |
property_ids | integer[] | Property filter |
Test workflow
- Prepare. Select the AppFolio setup for your workflow and review its starting records, including properties, tenants, work orders.
- Connect. Configure your agent with this world's URL and key using the SDK example. Check that it reaches the intended API before running a test.
- Define. Describe the task, expected final changes and records that must stay untouched. Keep expected outcomes separate from the agent's instructions.
- Run and inspect. Use the dashboard or your workflow's generated CLI setup. Review final records and changes, then rerun from the same starting setup with the relevant failure conditions. Use Deployment and CI to automate the same workflow.
What to verify
- WO-3301 urgent and assigned to an HVAC vendor
- WO-3302 assigned to a plumber with current insurance
- No work order sent to a vendor with expired insurance
- Duplicate requests merged into one work order
- WO-3303 left at low priority
Test file
A task file names the jobs, the policy your agent is given and what the grader reads back from the world's final state. The agent never sees the expected outcomes.
# worlds/tasks.yaml · AppFolio
version: 2
connector: appfolio
seed: appfolio-starter
mode: isolated
policy: >
Triage this morning's requests. Set urgent priority for no heat, no water
and leaks, dispatch each to a vendor in that trade with current insurance,
and merge duplicate requests.
tasks:
- id: triage-maintenance-requests-and-set-priority
prompt: Triage maintenance requests and set priority
- id: dispatch-work-orders-to-the-right-vendor
prompt: Dispatch work orders to the right vendor
- id: review-rental-applications-against-screening-rules
prompt: Review rental applications against screening rules
expected:
- WO-3301 urgent and assigned to an HVAC vendor
- WO-3302 assigned to a plumber with current insurance
- No work order sent to a vendor with expired insurance
- Duplicate requests merged into one work order
- WO-3303 left at low priority
scenarios:
- vendor-declines
- rate-limited
- duplicate-requestSee Tasks and outcomes for every field, and Deployment and CI to run the file on every pull request.
Failure conditions
Each one fires before the handler, at the same step on every run.
| condition | what the agent sees |
|---|---|
vendor-declines | The first vendor rejects the job and it returns to new |
rate-limited | API calls return 429 |
duplicate-request | A resident submits the same issue twice |
token-expires | The API credentials return 401 mid run |
Starting data
Start each run from the same records and relationships. The overview below describes the AppFolio starter; use the setup supplied for your workflow when preparing your own snapshot.
| Records | Starting setup |
|---|---|
| units | 120 across 3 properties |
| work orders | 40 across new, assigned, scheduled and completed |
| vendors | 12 with trades and insurance expiry dates |
| applications | 15 across new, screening and decision pending |
| leases | 110 active, 9 expiring this quarter |
The record shapes below reuse this world's API field definitions. They show illustrative values and placeholders, not an importable seed. API responses and seed input can differ; include all required records and references in the accepted import format for your workflow.
Properties records
Properties
Managed properties.
| Field | Type | Meaning / relationship |
|---|---|---|
id | integer | Property id |
name | string | Property name |
address | object | Address |
property_type | string | Type |
unit_count | integer | Number of units |
{
"id": 1,
"name": "<Property name>",
"address": {},
"property_type": "<Type>",
"unit_count": 1
}Tenants records
Tenants
Residents and lease holders.
| Field | Type | Meaning / relationship |
|---|---|---|
id | integer | Tenant id |
first_name | string | Given name |
last_name | string | Family name |
email | string | |
unit_id | integer | Unit |
move_in_on | date | Move-in date |
{
"id": 1,
"first_name": "<Given name>",
"last_name": "<Family name>",
"email": "person@example.test",
"unit_id": 1,
"move_in_on": "<Move-in date>"
}Work orders records
Work orders
Maintenance requests.
| Field | Type | Meaning / relationship |
|---|---|---|
id | integer | Work order id |
status | string | New, Assigned, Scheduled, Completed |
priority | string | Priority |
description | string | Problem description |
vendor_id | integer | Assigned vendor |
unit_id | integer | Unit |
{
"id": 1,
"status": "<New, Assigned, Scheduled, Completed>",
"priority": "<Priority>",
"description": "<Problem description>",
"vendor_id": 1,
"unit_id": 1
}Leases records
Leases
Lease terms and rent.
| Field | Type | Meaning / relationship |
|---|---|---|
id | integer | Lease id |
tenant_ids | integer[] | Tenants on the lease |
start_on | date | Lease start |
end_on | date | Lease end |
rent | number | Monthly rent |
status | string | Active, Past, Future |
{
"id": 1,
"tenant_ids": [],
"start_on": "<Lease start>",
"end_on": "<Lease end>",
"rent": 1,
"status": "<Active, Past, Future>"
}Reports records
Reports
Rent roll, delinquency and ledgers.
| Field | Type | Meaning / relationship |
|---|---|---|
results | object[] | Report rows |
next_page_url | string | Next page |
property_ids | integer[] | Property filter |
{
"results": [],
"next_page_url": "<Next page>",
"property_ids": []
}