Expand related resources
Instead of fetching 100 invoices and then 100 contacts to build a list, pass ?expand=contact. The related object is inlined on each row from a single batched lookup. Behavior mirrors Stripe and HubSpot's expand parameter.
How it works
- Original foreign-key stays on the response (
crm_company_id). Expanded value lands as a sibling property (company). - Lists do a single
IN-list fetch per expand — no N+1. 100 invoices withexpand=contact= 2 queries total (invoices + unique contacts). - Null foreign keys stay null — the expanded property is set to
nullon that row. - Max 3 expand paths per request. Comma-separated:
?expand=contact,dealor repeated:?expand=contact&expand=deal.
Example
# Inline company on every contact in the list — one request total. curl "https://app.staffifyai.com/api/workspace/v1/contacts?expand=company&limit=50" \ -H "Authorization: Bearer $STAFFIFY_API_KEY" # Multiple expands on a single resource — comma-separated. curl "https://app.staffifyai.com/api/workspace/v1/deals?expand=contact,company" \ -H "Authorization: Bearer $STAFFIFY_API_KEY" # Also works on retrieve endpoints. curl "https://app.staffifyai.com/api/workspace/v1/invoices/42?expand=contact,deal" \ -H "Authorization: Bearer $STAFFIFY_API_KEY"
Expandable paths
| Resource | expand= | Foreign key | Target | Required scope |
|---|---|---|---|---|
| contacts | company | crm_company_id | companies | crm.companies.read |
| deals | contact | crm_contact_id | contacts | crm.contacts.read |
| deals | company | crm_company_id | companies | crm.companies.read |
| invoices | contact | crm_contact_id | contacts | crm.contacts.read |
| invoices | deal | crm_deal_id | deals | crm.deals.read |
Permissions
Expanding a related resource requires the matching read-scope in addition to the scope of the resource you are querying. A key with only sales.invoices.read that tries GET /invoices?expand=contact gets a 403 EXPAND_SCOPE_MISSING. Mint a key with both scopes if you need the expansion.
Errors
422 UNKNOWN_EXPAND— expand path is not supported for this resource.422 TOO_MANY_EXPANDS— more than 3 paths were requested.403 EXPAND_SCOPE_MISSING— the API key lacks the read-scope of the expanded resource.
Not yet supported
- Dot-path chaining (
expand=contact.company) — single level only. - One-to-many expansion (invoice lines, team members per service) — foreign-key targets only.
- Expansion on workorders, quotes, bookings — contacts/deals/invoices only in V1.