Short Polling

Short Polling the FieldMotion API

Short polling is a simple way to keep another system up to date with FieldMotion data. Your integration stores a checkpoint timestamp, asks the FieldMotion API what changed after that checkpoint, fetches the changed records, processes them, then stores a new checkpoint for the next run.

This guide is intended for server-to-server integrations. It does not require a permanent connection, webhooks, or a custom FieldMotion feature.

When to use short polling

Use short polling when:

  • You need another system to pick up changes from FieldMotion every few minutes.

  • You can tolerate a short delay between a CRM edit and your system seeing it.

  • You want a simple, reliable integration that can retry after network failures.

Avoid short polling when:

  • You need sub-second updates.

  • You need to import very large historical datasets on every run.

  • You need guaranteed deletion events. Most changed-list endpoints return active records only, so deleted records may need a separate process or a custom integration.

API authentication

FieldMotion API calls are signed POST requests. The current public API documentation front page shows the same pattern.

For every request:

  1. Build the POST parameters.

  2. Add _api_now as the current Unix timestamp. Send it as a string.

  3. JSON-encode the POST parameters.

  4. Append | and your API key to that JSON string.

  5. MD5-hash the result.

  6. Add _api_md5 with the MD5 value.

  7. Add _api_id with your API key ID.

  8. POST the form data to https://cpXX.fieldmotion.com/a/<FunctionName>.

Important: convert integer and decimal values to strings before calculating _api_md5. This prevents JSON encoding differences between your client and the server.

Example base URL:

The exact cpXX server depends on the FieldMotion account.

Basic polling flow

The safest loop is:

  1. Read the last successful checkpoint from your database.

  2. Subtract a small overlap, such as 2 minutes, from that checkpoint.

  3. Call an ID-only changed-list endpoint, such as Customers_listByLastEdited.

  4. If IDs are returned, call the matching *_getById endpoint and request last_edited.

  5. Process each returned record idempotently.

  6. Store the maximum last_edited value that was successfully processed.

The overlap is important. It protects you from clock differences, records edited in the same second, and a failure that happens after fetching IDs but before processing all records. Because overlap means you may see the same record more than once, your integration should deduplicate by object type, ID, and last_edited.

Common changed-list endpoints

These endpoints accept:

They return an array of changed IDs.

Changed IDs endpoint
Follow-up detail endpoint
Notes

Customers_listByLastEdited

Customers_getById

Active customers changed after from.

Jobs_listByLastEdited

Jobs_getById

Active jobs changed after from; accepts optional form_id.

Assets_listByLastEdited

Assets_getById

Active assets changed after from.

AssetTypes_listByLastEdited

AssetTypes_getById

Asset type changes.

Tasks_listByLastEdited

Tasks_getById

Active tasks changed after from.

StockContainers_listByLastEdited

No generic detail endpoint in the current public API

Use only if your integration has an agreed stock-container follow-up path.

Some list endpoints also accept a last_edited filter and return records directly, for example:

  • Customers_list

  • Jobs_list

  • Users_list

  • Vehicles_list

  • Departments_list

  • Tasks_list

For larger integrations, prefer the ID-only endpoint plus a detail fetch. That keeps each polling step smaller and easier to retry.

Checkpoint rules

Store one checkpoint per object type. For example:

Recommended behavior:

  • Start with a deliberately old checkpoint for the first import, such as 2000-01-01 00:00:00.

  • Always request last_edited when fetching details.

  • Advance the checkpoint only after records are successfully written to your system.

  • If a request fails, keep the old checkpoint and retry later.

  • Use an overlap window on the next run.

  • Do not use your local machine time as the final checkpoint if you can use the returned last_edited values instead.

Polling interval

For most integrations, poll every 2 to 10 minutes. Do not poll continuously in a tight loop.

If a poll returns many records, finish processing the batch before immediately polling again. If your integration needs to process thousands of changes, add a queue on your side and process records at a steady rate.

Deletions and archived records

Most changed-list endpoints filter out deleted records. That means short polling is good for detecting creates and updates, but not always sufficient for detecting deletions.

If your integration must mirror deletions exactly, discuss that requirement before implementation. A separate export, audit log, or custom endpoint may be needed depending on the object type.

PHP example

This example polls changed customers, fetches their details, and advances a checkpoint after successful processing.

Python example

This example uses only Python standard library modules.

JavaScript / Node.js example

This example uses Node.js 18 or newer, where fetch is available globally.

C# example

This example uses HttpClient and System.Text.Json.

Error handling checklist

Your polling worker should:

  • Log every API error response.

  • Retry temporary network failures with backoff.

  • Keep the old checkpoint when a poll fails.

  • Treat duplicate records as normal.

  • Store enough information to replay a failed batch.

  • Alert if polling has not succeeded for longer than expected.

Suggested production setup

A typical production integration has:

  • One scheduled worker per object type.

  • One durable checkpoint per object type.

  • A local queue or staging table for changed records.

  • Idempotent upsert logic in the target system.

  • Monitoring for API failures and stale checkpoints.

For example, a customer sync might run every 5 minutes:

This pattern keeps the integration simple, recoverable, and gentle on the FieldMotion API.

Last updated