Skip to main content

Purchase Orders

NewBetaWrite

Purchase Order objects represent purchase orders issued to vendors in AppFolio®. Skywalk API lets you list the purchase orders in your account as they appear on AppFolio®'s Purchase Orders screen, retrieve one purchase order in full detail with its line items, and create new purchase orders.

The Purchase Order Object

One object per row of AppFolio®'s Purchase Orders screen (Maintenance > Purchase Orders), as displayed. The list row does not include line items; see The Purchase Order Detail Object for the full record.

Attributes


appfolioIdstring
AppFolio ID of the purchase order. Pass it to GET /purchase-orders/<appfolioId> to retrieve the purchase order's full detail.
Example:
"17"

numberstring
Purchase order number, as displayed.
Example:
"1042"

createdOnstring
Date the purchase order was created, as displayed (MM/DD/YYYY).
Example:
"08/01/2026"

propertyNamestring
Property the purchase order's line items are for, as displayed in the Purchase Orders screen's "For" column, e.g. "Warm Weather Apartments - 3B" when the lines name one property and unit. Purchase orders spanning several properties show a combined label; null when no line item names a property.
Example:
"Warm Weather Apartments"

vendorNamestring
Display name of the vendor the purchase order is issued to.
Example:
"ACME Plumbing Inc."

approvalStatusstring
Approval status of the purchase order as displayed on the Purchase Orders screen: Pending Approval, Approved or Pending Revision.
Example:
"Approved"

completedboolean
Whether the purchase order has been marked completed.
Example:
false

glAccountNamestring
GL account the purchase order's line items are coded to, as displayed (number and name, e.g. "216-240: Unit:Plumbing Repairs"). "Multiple" when the lines are coded to different GL accounts; null when no line item names one.
Example:
"216-240: Unit:Plumbing Repairs"

amountstring
Total amount of the purchase order as a decimal string such as "1250.00", without a currency symbol.
Example:
"1250.00"

The Purchase Order Object
{
"appfolioId": "17",
"number": "1042",
"createdOn": "08/01/2026",
"propertyName": "Warm Weather Apartments",
"vendorName": "ACME Plumbing Inc.",
"approvalStatus": "Approved",
"completed": false,
"glAccountName": "216-240: Unit:Plumbing Repairs",
"amount": "1250.00"
}

Get All Purchase Orders

GET /v1/purchase-orders NewBeta

Follows: AuthenticationCachingPollingList Response FormatScheduled Job

The purchase orders endpoint returns a list of all purchase orders in your AppFolio® account — the same rows, values and visibility a user sees on the Purchase Orders screen. Narrow the list with the same filters that screen offers: a creation date range, approval status, whether the order is completed or submitted, a property, a vendor or a GL account. Canceled purchase orders are left out unless you ask for them with includeCanceled. Line items are not part of the list; fetch one purchase order's detail with Get One Purchase Order. This endpoint should respond immediately with your most recently cached data.

Parameters


createdOnFromdate
Earliest creation date to include, as MM/DD/YYYY. May be used without createdOnTo.

createdOnTodate
Latest creation date to include, as MM/DD/YYYY. May be used without createdOnFrom.

approvalStatusselect
Approval status to include, as shown on the Purchase Orders screen: Pending Approval, Approved or Pending Revision. Defaults to All.
Default Value:  
All
Possible Values:  
All
Pending Approval
Approved
Pending Revision

completedboolean
Set true to return only purchase orders marked completed, or false for those not yet completed. When omitted, both are returned.

submittedboolean
Set true to return only purchase orders marked as submitted to the vendor, or false for those not yet submitted. When omitted, both are returned.

includeCanceledboolean
Set true to include canceled purchase orders. Defaults to false: canceled purchase orders are left out, as they are on the Purchase Orders screen.

propertyIdselect
AppFolio ID of a property. When provided, returns only purchase orders with a line item for that property. The property must exist and be visible to your connected AppFolio user.

vendorIdstring
AppFolio ID of a vendor. When provided, returns only purchase orders issued to that vendor. The vendor must exist and be visible to your connected AppFolio user. Look vendors up with the Vendors endpoint.

glAccountIdstring
AppFolio ID of a GL account. When provided, returns only purchase orders with a line item coded to that GL account. Look GL accounts up with the GL Accounts endpoint.

 

Returns


The standard List Response Format with a data property containing an array of Purchase Order objects.

GET /v1/purchase-orders
curl -X GET 'https://api.skywalkapi.com/v1/purchase-orders' \
-H "X-API-Key: PUT_YOUR_API_KEY_HERE"
Response
{
"meta": {
"status": "ok",
"path": "/v1/purchase-orders",
"count": 2,
"lastUpdated": 1610992228
},
"links": {
"next": "/v1/purchase-orders?cursor=abcdefg"
},
"data": [
{
"appfolioId": "17",
"number": "1042",
"createdOn": "08/01/2026",
"propertyName": "Warm Weather Apartments",
"vendorName": "ACME Plumbing Inc.",
"approvalStatus": "Approved",
"completed": false,
"glAccountName": "216-240: Unit:Plumbing Repairs",
"amount": "1250.00"
},
{
"appfolioId": "18",
"number": "1043",
"createdOn": "08/03/2026",
"propertyName": "Sample Property",
"vendorName": "Example Landscaping, LLC",
"approvalStatus": "Pending Approval",
"completed": false,
"glAccountName": "206-330: Landscape",
"amount": "480.00"
}
]
}

Get One Purchase Order

GET /v1/purchase-orders/:appfolioId NewBeta

Follows: AuthenticationCachingPollingList Response FormatScheduled Job

Returns one purchase order in full detail — the header fields, the vendor it is issued to, its ship-to address, the work orders and bills linked to it, and every line item. Look purchase order IDs up with Get All Purchase Orders. To enter a vendor's invoice against the order, pass its appfolioId as purchaseOrderId to Create a Bill; the new bill then appears in billIds.

Parameters


appfolioIdstring
The purchase order's appfolioId, as returned by the Purchase Orders endpoint. Supplied in the path: GET /purchase-orders/<appfolioId>.

 

Returns


The standard List Response Format with a data property containing an array with the requested Purchase Order Detail object.

GET /v1/purchase-orders/:appfolioId
curl -X GET 'https://api.skywalkapi.com/v1/purchase-orders/17' \
-H "X-API-Key: PUT_YOUR_API_KEY_HERE"
Response
{
"meta": {
"status": "ok",
"path": "/v1/purchase-orders/17",
"count": 1,
"lastUpdated": 1610992228
},
"links": {},
"data": [
{
"appfolioId": "17",
"number": "1042",
"amount": "1250.00",
"approvalStatus": "Approved",
"requiresApproval": true,
"approved": true,
"partiallyApproved": false,
"nextApprovers": null,
"lastApprovedBy": "Jane Smith",
"completed": false,
"billed": false,
"canceled": false,
"createdAt": "2026-08-01T15:04:05Z",
"requiredBy": "08/15/2026",
"orderSubmittedDate": null,
"invoiceNumber": "INV-1042",
"instructions": "Deliver to the leasing office between 9am and 4pm.",
"revisionInstructions": null,
"taxPercentage": null,
"vendorId": "466",
"vendorName": "ACME Plumbing Inc.",
"companyName": null,
"supplierName": null,
"shipToPropertyId": "12",
"shipToPropertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"shipToPortfolioId": null,
"workOrderIds": [
"210"
],
"billIds": [],
"createdByName": "Jane Smith",
"lineItems": [
{
"appfolioId": "41",
"description": "Sprinkler head replacement",
"quantity": "2",
"itemAmount": "125.00",
"shippingAmount": "0.00",
"taxAmount": "0.00",
"receivedAt": null,
"glAccountId": "204",
"glAccountName": "216-240: Unit:Plumbing Repairs",
"propertyId": "12",
"propertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"unitId": "48",
"unitName": "3B",
"inventoryName": null
},
{
"appfolioId": "42",
"description": "Labor",
"quantity": "1",
"itemAmount": "1000.00",
"shippingAmount": "0.00",
"taxAmount": "0.00",
"receivedAt": null,
"glAccountId": "204",
"glAccountName": "216-240: Unit:Plumbing Repairs",
"propertyId": "12",
"propertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"unitId": "48",
"unitName": "3B",
"inventoryName": null
}
]
}
]
}

The Purchase Order Detail Object

One purchase order in full — the header fields, the vendor it is issued to, its ship-to address, the work orders and bills linked to it, and every line item. Get One Purchase Order returns this object, and so does Create a Purchase Order for the newly created purchase order.

Attributes


appfolioIdstring
AppFolio ID of the purchase order.
Example:
"17"

numberstring
Purchase order number.
Example:
"1042"

amountstring
Total amount of the purchase order as a decimal string such as "1250.00", without a currency symbol.
Example:
"1250.00"

approvalStatusstring
Approval status of the purchase order: Pending Approval, Approved or Pending Revision.
Example:
"Approved"

approvedboolean
Whether the purchase order has been fully approved.
Example:
true

completedboolean
Whether the purchase order has been marked completed.
Example:
false

billedboolean
Whether a bill has been created from the purchase order.
Example:
false

canceledboolean
Whether the purchase order has been canceled.
Example:
false

createdAtstring
When the purchase order was created, as an ISO 8601 timestamp.
Example:
"2026-08-01T15:04:05Z"

requiredBystring
Date the order is required by, as MM/DD/YYYY, or null when none was set.
Example:
"08/15/2026"

invoiceNumberstring
Vendor invoice number recorded on the purchase order, or null when none was entered.
Example:
"INV-1042"

instructionsstring
Instructions to the vendor, or null when none were entered.
Example:
"Deliver to the leasing office between 9am and 4pm."

vendorIdstring
AppFolio ID of the vendor the purchase order is issued to. Null when it is issued to your management company or a supplier instead.
Example:
"466"

vendorNamestring
Display name of the vendor the purchase order is issued to, or null.
Example:
"ACME Plumbing Inc."

shipToPropertyIdstring
AppFolio ID of the property the order ships to, or null when no ship-to address was set.
Example:
"12"

workOrderIdsstring[]
AppFolio IDs of the work orders the purchase order is associated with. Look them up with the Work Orders endpoint.
Example:
["210"]

billIdsstring[]
AppFolio IDs of the bills created from this purchase order. Pass one to GET /bills/<appfolioId> for the bill's detail.
Example:
[]

lineItemsPurchaseOrderLineItem[]
Line items on the purchase order. Each entry has "appfolioId", "description", "quantity", "itemAmount" (per-unit cost), "shippingAmount", "taxAmount", "receivedAt" (an ISO 8601 timestamp, or null while not received), "glAccountId", "glAccountName", "propertyId", "propertyName", "unitId", "unitName" and "inventoryName".
Example:
[{"appfolioId":"41","description":"Sprinkler head replacement","quantity":"2","itemAmount":"125.00","shippingAmount":"0.00","taxAmount":"0.00","receivedAt":null,"glAccountId":"204","glAccountName":"216-240: Unit:Plumbing Repairs","propertyId":"12","propertyName":"Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001","unitId":"48","unitName":"3B","inventoryName":null},{"appfolioId":"42","description":"Labor","quantity":"1","itemAmount":"1000.00","shippingAmount":"0.00","taxAmount":"0.00","receivedAt":null,"glAccountId":"204","glAccountName":"216-240: Unit:Plumbing Repairs","propertyId":"12","propertyName":"Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001","unitId":"48","unitName":"3B","inventoryName":null}]


More Attributes


requiresApprovalboolean

partiallyApprovedboolean

nextApproversstring

lastApprovedBystring

orderSubmittedDatestring

revisionInstructionsstring

taxPercentagestring

companyNamestring

supplierNamestring

shipToPropertyNamestring

shipToPortfolioIdstring

createdByNamestring

The Purchase Order Detail Object
{
"appfolioId": "17",
"number": "1042",
"amount": "1250.00",
"approvalStatus": "Approved",
"requiresApproval": true,
"approved": true,
"partiallyApproved": false,
"nextApprovers": null,
"lastApprovedBy": "Jane Smith",
"completed": false,
"billed": false,
"canceled": false,
"createdAt": "2026-08-01T15:04:05Z",
"requiredBy": "08/15/2026",
"orderSubmittedDate": null,
"invoiceNumber": "INV-1042",
"instructions": "Deliver to the leasing office between 9am and 4pm.",
"revisionInstructions": null,
"taxPercentage": null,
"vendorId": "466",
"vendorName": "ACME Plumbing Inc.",
"companyName": null,
"supplierName": null,
"shipToPropertyId": "12",
"shipToPropertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"shipToPortfolioId": null,
"workOrderIds": [
"210"
],
"billIds": [],
"createdByName": "Jane Smith",
"lineItems": [
{
"appfolioId": "41",
"description": "Sprinkler head replacement",
"quantity": "2",
"itemAmount": "125.00",
"shippingAmount": "0.00",
"taxAmount": "0.00",
"receivedAt": null,
"glAccountId": "204",
"glAccountName": "216-240: Unit:Plumbing Repairs",
"propertyId": "12",
"propertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"unitId": "48",
"unitName": "3B",
"inventoryName": null
},
{
"appfolioId": "42",
"description": "Labor",
"quantity": "1",
"itemAmount": "1000.00",
"shippingAmount": "0.00",
"taxAmount": "0.00",
"receivedAt": null,
"glAccountId": "204",
"glAccountName": "216-240: Unit:Plumbing Repairs",
"propertyId": "12",
"propertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"unitId": "48",
"unitName": "3B",
"inventoryName": null
}
]
}

Create a Purchase Order

POST /v1/purchase-orders Write

Follows: AuthenticationCachingPollingList Response Format

Creates a new purchase order issued to a vendor, with its line items.

Depending on your AppFolio configuration, creating a purchase order may enter an approval workflow and notify approvers. The vendor must already exist; create one first with Create a Vendor if needed. Purchase orders issued to your management company or to a supplier, and ship-to portfolios, are not yet supported.


Parameters


vendorIdstring
AppFolio ID of the vendor the purchase order is issued to. Look vendors up with the Vendors endpoint.

lineItemsmulti
Line items for the purchase order, as a JSON array. Each entry requires "glAccountId", "propertyId" and "itemAmount" (the per-unit cost as a decimal string such as "125.00"), and may carry "quantity" (a whole number as a string such as "2"; defaults to "1"), "description" and "unitId". At least one line item is required.

shipToPropertyIdstring
AppFolio ID of the property the order ships to. When omitted, no ship-to address is set.

workOrderIdsmulti
AppFolio IDs of work orders to associate the purchase order with, as a JSON array of strings. Look work orders up with the Work Orders endpoint.

requiredBystring
Date the order is required by, as MM/DD/YYYY.

invoiceNumberstring
Vendor invoice number to record on the purchase order.

instructionsstring
Instructions to the vendor, shown on the purchase order.

numberstring
Purchase order number. When omitted, AppFolio assigns the next number automatically.

 

Returns


The standard List Response Format with a data property containing an array with the created purchase order as a Purchase Order Detail object.

The response reflects the purchase order as stored in AppFolio, not the request as submitted — the same shape Get One Purchase Order returns, not the list row. When number was omitted, the response carries the number AppFolio assigned.

POST /v1/purchase-orders
curl -X POST 'https://api.skywalkapi.com/v1/purchase-orders' \
-H "X-API-Key: PUT_YOUR_API_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"vendorId": "466",
"shipToPropertyId": "12",
"workOrderIds": [
"210"
],
"requiredBy": "08/15/2026",
"invoiceNumber": "INV-1042",
"instructions": "Deliver to the leasing office between 9am and 4pm.",
"lineItems": [
{
"glAccountId": "204",
"propertyId": "12",
"unitId": "48",
"itemAmount": "125.00",
"quantity": "2",
"description": "Sprinkler head replacement"
},
{
"glAccountId": "204",
"propertyId": "12",
"unitId": "48",
"itemAmount": "1000.00",
"description": "Labor"
}
]
}'
Response
{
"meta": {
"status": "ok",
"path": "/v1/purchase-orders",
"query": {
"vendorId": "466",
"shipToPropertyId": "12",
"workOrderIds": [
"210"
],
"requiredBy": "08/15/2026",
"invoiceNumber": "INV-1042",
"instructions": "Deliver to the leasing office between 9am and 4pm.",
"lineItems": [
{
"glAccountId": "204",
"propertyId": "12",
"unitId": "48",
"itemAmount": "125.00",
"quantity": "2",
"description": "Sprinkler head replacement"
},
{
"glAccountId": "204",
"propertyId": "12",
"unitId": "48",
"itemAmount": "1000.00",
"description": "Labor"
}
]
},
"count": 1,
"lastUpdated": 1610992228
},
"errors": [],
"data": [
{
"appfolioId": "17",
"number": "1042",
"amount": "1250.00",
"approvalStatus": "Approved",
"requiresApproval": true,
"approved": true,
"partiallyApproved": false,
"nextApprovers": null,
"lastApprovedBy": "Jane Smith",
"completed": false,
"billed": false,
"canceled": false,
"createdAt": "2026-08-01T15:04:05Z",
"requiredBy": "08/15/2026",
"orderSubmittedDate": null,
"invoiceNumber": "INV-1042",
"instructions": "Deliver to the leasing office between 9am and 4pm.",
"revisionInstructions": null,
"taxPercentage": null,
"vendorId": "466",
"vendorName": "ACME Plumbing Inc.",
"companyName": null,
"supplierName": null,
"shipToPropertyId": "12",
"shipToPropertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"shipToPortfolioId": null,
"workOrderIds": [
"210"
],
"billIds": [],
"createdByName": "Jane Smith",
"lineItems": [
{
"appfolioId": "41",
"description": "Sprinkler head replacement",
"quantity": "2",
"itemAmount": "125.00",
"shippingAmount": "0.00",
"taxAmount": "0.00",
"receivedAt": null,
"glAccountId": "204",
"glAccountName": "216-240: Unit:Plumbing Repairs",
"propertyId": "12",
"propertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"unitId": "48",
"unitName": "3B",
"inventoryName": null
},
{
"appfolioId": "42",
"description": "Labor",
"quantity": "1",
"itemAmount": "1000.00",
"shippingAmount": "0.00",
"taxAmount": "0.00",
"receivedAt": null,
"glAccountId": "204",
"glAccountName": "216-240: Unit:Plumbing Repairs",
"propertyId": "12",
"propertyName": "Warm Weather Apartments - 1234 Warm Weather Rd., CA 90001",
"unitId": "48",
"unitName": "3B",
"inventoryName": null
}
]
}
]
}