Appearance
API Calls - Overview ​
Choose the right API utility for your use case.
Decision Tree ​
Follow these steps:
Are you calling the API inside a function/event handler?
- ✅ Yes → Use
$apiFetch - ❌ No → Continue to step 2
- ✅ Yes → Use
Is the data organization-specific? (Should it auto-refresh when user switches orgs?)
- ✅ Yes → Use
useOrgApi - ❌ No → Use
useApi
- ✅ Yes → Use
Quick Comparison ​
| Feature | useApi | useOrgApi | $apiFetch |
|---|---|---|---|
| When to use | Component setup, reactive data | Org-specific data, auto-refreshes on org change | Event handlers, functions, form submissions |
| Returns | { data, error, pending, refresh } | { data, error, pending, refresh } | Promise<T> |
| Reactive | ✅ Yes | ✅ Yes | ❌ No |
| Auto-refresh on org change | ❌ No | ✅ Yes | ❌ No |
| Type safety | âś… Full | âś… Full | âś… Full |
Examples ​
useApi - General Data ​
typescript
// User data, auth, public data
const { data: user } = useApi('/api/v1/auth/me', { lazy: true })useOrgApi - Organization Data ​
typescript
// Almost everything in /hr/:orgId routes
// Auto-refreshes when user switches organizations
const { data } = useOrgApi('/api/organizations/...', { lazy: true })$apiFetch - Programmatic Calls ​
typescript
// Form submissions, delete actions, etc.
const { $apiFetch } = useGetApiFetch()
const handleSubmit = async () => {
await $apiFetch('/api/organizations/employees', {
method: 'post',
body: formData
})
}Key Rules ​
Pro Tips
- Always use
lazy: truewith useApi/useOrgApi for better UX - Use
useOrgApifor org data - handles org switching automatically - Use
$apiFetchin event handlers - simpler and more direct - Types are auto-generated - you get full autocomplete!
Never Do This
typescript
// ❌ Don't use useFetch or $fetch directly
const { data } = useFetch('/api/endpoint')
const data = await $fetch('/api/endpoint')
// âś… Always use our wrappers
const { data } = useApi('/api/endpoint', { lazy: true })
const data = await $apiFetch('/api/endpoint')Deep Dives: