Errors & Retries | FieldCamp API
Response envelope format, HTTP status codes, and retry guidance for the FieldCamp API.
Every response follows the same shape: a top-level success boolean plus
either data (on success) or error (on failure).
Success envelope
{
"success": true,
"data": {
"job": { "id": "job_abc123", "...": "..." }
}
}The shape of data varies by endpoint. The per-endpoint reference pages
document each one.
Error envelope
{
"success": false,
"error": "jobNumber is required"
}Status codes
| Code | Meaning | Retry? |
|---|---|---|
200 | Success | — |
400 | Validation error — fix your payload | No |
401 | Authentication failed — bad or expired JWT | No |
403 | Authorization failed — your tenant doesn't have access | No |
404 | Resource not found | No |
409 | Conflict — e.g. duplicate jobNumber | No, handle idempotently |
429 | Rate limited | Yes, with backoff |
500 | Server error | Yes, with exponential backoff |
502 503 504 | Gateway / upstream issues | Yes, with exponential backoff |
Recommended retry policy
- 5xx: retry up to 3 times with exponential backoff — 1 s, 2 s, 4 s.
- 429: same pattern; if responses include a
Retry-Afterheader, honor it. - 4xx: do not retry. Fix the payload or the auth, then re-submit.
- Network errors: retry up to 3 times with the same backoff as 5xx.
Reference implementation:
async function retryingRequest(fn, attempt = 0) {
try {
return await fn();
} catch (err) {
const status = err.response?.status;
const retryable = !status || status >= 500 || status === 429;
if (retryable && attempt < 3) {
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
return retryingRequest(fn, attempt + 1);
}
throw err;
}
}Common errors
401 Unauthorized — Invalid or expired token
Your JWT is missing, malformed, or expired.
Check:
- The
Authorizationheader is exactlyBearer <jwt>(one space, no quotes). - You're also sending
X-API-Key: <jwt>(both are required today). - The JWT string has no whitespace or newlines.
If the key recently worked and now fails, email support to rotate it.
400 Validation error — jobNumber is required
Your POST /api/jobs payload is missing a required field. Most common
causes:
- You sent the request as JSON instead of
multipart/form-data. See the Jobs reference. jobDatacontains a JSON string, but is missing one of the required top-level fields. See the NewJobData schema.- A field name is misspelled — field names are case-sensitive.
409 Conflict — duplicate jobNumber
A job with that jobNumber already exists in your tenant. See
Idempotency for the recommended lookup-then-create
pattern so retries are safe.
500 Internal server error
Something went wrong on our side. Retry with exponential backoff. If it persists beyond three retries, capture the request ID from response headers and email support@fieldcamp.ai.
ID fields
Quirk: the same object can come back with different ID field names
across endpoints — id, recordId, or _id. Code defensively:
const resourceId =
response.data.data.resource.id ??
response.data.data.resource.recordId ??
response.data.data.resource._id;Prefer id when present. Normalization is on the roadmap.