Using the FieldPulse API
So you want to build something with the FieldPulse API — cool. I've been down this road a few times (yeah, the OAuth flow tripped me up the first time too), and this doc should get you from zero to your first successful API call without too much head-scratching.
What You're Working With
The FieldPulse API is a RESTful JSON API. It's pretty standard stuff:
- Base URL:
https://api.fieldpulse.com/v2 - Request format: JSON
- Response format: JSON
- Authentication: OAuth 2.0 with Bearer tokens
We rate limit at 100 requests per minute per token. Hit that and you'll get a 429 with a Retry-After header — more on that below.
Authentication: Getting Your Token
First things first — you need credentials. Head to Admin > API & Integrations in your FieldPulse account and generate an API key. You'll get a client_id and client_secret.
Here's the token exchange. This one's tripped up a lot of folks because the docs used to say grant_type=client_token which... nope, it's client_credentials.
POST https://auth.fieldpulse.com/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
&scope=work_orders:read work_orders:write customers:read
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "work_orders:read work_orders:write customers:read"
}
Heads up: That token expires in an hour. You'll want to refresh it before then — or just cache it and handle the 401 when it comes. In my experience, the latter is easier unless you're doing something real-time.
Making Your First Request
Once you've got your token, the rest is pretty straightforward. Let's grab a list of work orders:
GET https://api.fieldpulse.com/v2/work_orders?status=scheduled&limit=25
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Accept: application/json
Response structure looks like this:
{
"data": [
{
"id": "wo_abc123",
"customer_id": "cust_xyz789",
"status": "scheduled",
"scheduled_start": "2026-04-15T09:00:00Z",
"scheduled_end": "2026-04-15T11:00:00Z",
"technician_ids": ["tech_001", "tech_002"],
"location": {
"address_line1": "123 Main St",
"city": "Austin",
"state": "TX",
"postal_code": "78701"
},
"custom_fields": {
"priority": "high",
"equipment_type": "HVAC"
}
}
],
"meta": {
"total": 156,
"page": 1,
"per_page": 25,
"has_more": true
}
}
Note the meta object — you'll need that for pagination. More on that in a sec.
Common Patterns
Pagination
The API uses cursor-based pagination now (it used to be offset-based, which got slow at scale). Grab the next_cursor from meta and pass it as a query param:
GET /v2/work_orders?cursor=eyJpZCI6IndvX3h5ejk...&limit=25
Worth noting: If you're exporting a large dataset, expect this to take a few minutes. The API will happily serve you thousands of records, but don't hammer it with parallel requests — you'll hit rate limits fast.
Filtering
Most list endpoints support filtering by date range, status, and related IDs. The syntax is:
GET /v2/work_orders?status=completed&scheduled_after=2026-04-01T00:00:00Z&technician_id=tech_001
Date filters are inclusive of the start, exclusive of the end — yeah, I know, it's a bit weird. I actually filed a bug on this years ago and apparently it's "working as designed." So... plan accordingly.
Error Handling
The API returns consistent error shapes:
{
"error": "validation_error",
"message": "Invalid value for scheduled_start",
"details": [
{
"field": "scheduled_start",
"code": "invalid_format",
"message": "Expected ISO 8601 datetime"
}
]
}
Common status codes:
400— Bad request, check your JSON401— Token expired or invalid403— Your token doesn't have the right scope404— Resource not found409— Conflict (e.g., trying to modify a completed work order)429— Rate limited, checkRetry-After
Creating and Updating Records
POST and PATCH follow similar patterns. Here's creating a work order:
POST /v2/work_orders
Authorization: Bearer ...
Content-Type: application/json
{
"customer_id": "cust_xyz789",
"service_type": "maintenance",
"scheduled_start": "2026-04-20T14:00:00Z",
"scheduled_end": "2026-04-20T16:00:00Z",
"technician_ids": ["tech_001"],
"location": {
"address_line1": "456 Oak Ave",
"city": "Austin",
"state": "TX"
}
}
The response will include the created record with its generated id. If you need to assign multiple technicians, just add more IDs to that array — though heads up, there's a limit of 5 per work order.
Webhooks vs. Polling
If you're building something that needs to react to changes, don't poll. We have webhooks — see Setting Up Webhooks for the full setup. The short version: you can subscribe to events like work_order.created, work_order.status_changed, job.completed, etc.
Polling the API every few minutes for updates is... not great. You'll hit rate limits and your integration will be laggy. Use webhooks when you can.
Rate Limiting and Backoff
When you hit 429, back off exponentially. Something like:
const delay = Math.pow(2, retryCount) * 1000; // 1s, 2s, 4s, 8s...
Don't ignore the Retry-After header — it's there for a reason. And if you're doing bulk operations, consider using the Bulk Import API instead of hitting the regular endpoints hundreds of times.
SDKs and Tools
We don't have official SDKs (yet?), but the community has put together some solid options:
- Node.js:
fieldpulse-clienton npm — unofficial but well-maintained - Python: There's a requests-based wrapper in the forums somewhere
- Postman: Import our OpenAPI spec from
https://api.fieldpulse.com/v2/openapi.json
For local webhook testing, ngrok is your friend. Or cloudflared tunnel if you're fancy.
Edge Cases That'll Get You
A few things I've personally stubbed my toe on:
- Time zones: All datetimes in the API are UTC. Convert on your end.
- Deleted records: We soft-delete. Check the
deleted_atfield — it might be non-null. - Custom fields: These vary by account. Query
/v2/custom_fieldsfirst to see what's available. - Technician availability: The API won't stop you from double-booking — that's checked at scheduling time, not API validation time.
Getting Help
API questions can get technical fast. If you're stuck:
- Check the API Rate Limits and Best Practices doc
- Post in the Developers forum with your request ID (it's in the
X-Request-IDresponse header) - For enterprise support, open a ticket through your account rep
And yeah — if something in this doc is wrong or out of date, let me know. The API changes sometimes and I don't always catch every update.
See Also
- Setting Up Webhooks
- API Rate Limits and Best Practices
- Single Sign-On (SSO) Configuration
- Discussion: Who's integrated FieldPulse with their CRM?