The MyGeotab software development kit (SDK) exposes the same platform capabilities that power MyGeotab. This flexibility means the integration must make deliberate choices about data access, identity, scale, recovery, and side effects. Use this guide before the method and entity reference to choose a pattern and avoid common production failures.

Choosing an integration pattern

Start with the behavior your application needs, not with an API method. The wrong access pattern can work in a test database and then become slow, incomplete, or difficult to recover at customer scale.

NeedUseWhy
Read current state or answer a bounded questionGetSearch, property selection, sorting, and supported pagination make the request explicit and bounded.
Continuously synchronize changesGetFeedA durable version cursor avoids repeatedly scanning the same history and returns later corrections.
Run analytics over large historical data setsData ConnectorAnalytics workloads do not have to compete with operational API traffic or maintain polling infrastructure.
Combine a small number of independent, short readsExecuteMultiCallOne HTTP round trip reduces network overhead while preserving result order.
Add a workflow inside MyGeotab or Geotab DriveAdd-InThe application can use the host context and the signed-in user's data scope.

These patterns can coexist. For example, an Add-In can use Get for an interactive view while a server-side process usesGetFeed to maintain a local operational store. Confirm that the entities and fields you need are supported by the selected pattern before committing to the architecture.

Setting access boundaries

The API applies the authenticated user's security clearances and data-access groups. A successful call can therefore return an empty or partial result when the same call returns data for an administrator. Design and test with the permissions the integration will use in production.

  • Use a dedicated API user so that a person's password, role change, or departure does not interrupt the integration.
  • Grant only the clearances and data scope required for the use case. Treat unexpectedly empty results as a possible scope issue.
  • Use a test database and test entities for development. The API Runner and code samples call a real database; they are not a sandbox.
  • Check beta status, required clearances, database features, and server support for every entity and method your integration depends on.

Changing the API user or its data scope can change which records are visible. Revalidate snapshots and feed checkpoints after an access change instead of assuming the old state is complete for the new scope.

Managing authentication

Authenticate once, retain the returned credentials securely, and reuse the session. Reauthenticating before every request adds latency, consumes the lower authentication rate limit, and eventually invalidates older sessions for the same user.

  1. Authenticate against my.geotab.comunless you already know the customer's server.
  2. Read the returned LoginResult.path. If it is not ThisServer, send subsequent requests to that server. A database can move, so use an API client that handles federation or retain this redirect behavior in your client.
  3. Store credentials as secrets. Never log passwords, session IDs, bearer tokens, cookies, or complete request bodies containing them.
  4. When an authenticated call returns InvalidUserException or an invalid-session error, refresh or authenticate once, then retry the original call once. Repeated authentication is not a recovery strategy for permission or request errors.

Sessions can expire because of age, a password change, or the per-user concurrent-session limit. See the authentication lifecycle and current rate limits for details.

Reading current state

A Get call without a search can return every accessible entity of that type. Make broad reads intentional by adding a supported search, a result limit, and pagination where the entity supports it.

Rough edgeReliable approach
Search objects are entity-specific, and similarly named fields can have different meanings.Use the search object documented for the requested entity. Read each property description; for example, an entityFromDate can describe its active lifecycle rather than its creation time.
Names can use wildcard matching and are not guaranteed to be unique.Resolve a name to exactly one entity, reject ambiguous matches, and retain the returned ID for later calls.
Entity IDs are opaque and some system IDs are readable constants rather than GUIDs.Treat IDs as opaque strings. Do not reject an ID only because it is not a GUID.
resultsLimit truncates a response; by itself, it does not prove that the complete result was returned.For entities that support pagination, pass a supported sort object and carry both offset and lastIdfrom the final row. See pagination.
PropertySelector is beta and is not supported by every entity, property, or search combination.Use it only where documented, include id when the result will be joined or updated, and test the selected fields on every supported server version. An empty field list returns the default full object.
Nested entity properties commonly contain only an ID.Load referenced entities in bounded batches and cache stable reference data such as devices, diagnostics, sources, and users instead of issuing one request per record.
Telemetry queries can accidentally scan an unbounded history.Supply UTC fromDate and toDate bounds where supported, particularly when filteringStatusData, LogRecord, faults, trips, and other high-volume records. See the Telemetry and Diagnostics guide for diagnostic filtering, units, interpolation, and bounded fallback behavior.

Use ExecuteMultiCall for a modest number of independent, short reads. Calls run in order and stop at the first error; later calls are not executed. Keep long-running or large-response calls separate, and limit nested calls to the recommended maximum described in the MultiCall guide.

Paginating with JavaScript

This browser-side pattern uses the JavaScript API client to retrieve a complete, bounded device list. It retains both pagination cursor values because device names are not unique, and it continues until the API returns an empty page. A short page alone is not proof that pagination is complete.

If the integration needs only one device, search by an exact ID or serial number and set resultsLimit to a small value. If a human-entered name matches more than one result, ask for a more precise selector instead of choosing the first result.

Paginating with .NET

The equivalent server-side pattern uses the Geotab.Checkmate.ObjectModel NuGet package. The client handles JSON serialization and authentication federation.

Keep the NuGet package current and compile examples against the package version your application deploys. The .NET client guide covers setup and client behavior.

Synchronizing changes

Treat a GetFeed cursor as a durable checkpoint, not as a timestamp. Maintain an independent checkpoint for each database, entity type, and integration scope.

  1. Choose an initial position. Omit fromVersion to start from now, use "0" for available history, or use a supported fromDate search on the first request to seed from a date.
  2. On later requests, pass the previous response's toVersion as fromVersion. Do not repeat the date-to-version search on every restart.
  3. Use a dedicated API user with CompanyGroup root scope for full-fleet synchronization. A user scoped below the root can make feed queries materially slower and can cause a 180-second timeout. Use bounded Get queries when the integration must read only a restricted subset.
  4. Persist each batch with idempotent upserts. A feed can return corrected older data, not only newly created records.
  5. Save toVersion only after the entire batch is durably processed. Saving it first can lose records if the process fails before the batch is committed. Saving it afterward can replay a batch, so processing must be idempotent.
  6. Poll again immediately after a full batch, use a short baseline wait after a partial batch, and progressively back off after empty batches.

Search support differs by feed type, and many search properties are ignored. Check the GetFeed reference before relying on a filter. See the Data Feed guide for calculated-data invalidation, trip identity, and type-specific limits.

Writing data safely
  • Treat Add, Set, and Remove as production changes. Use test entities and require an explicit environment or database check in maintenance tools.
  • Construct Add entities with all fields required by that entity type. For Set, retrieve the current entity, apply the intended change, preserve its ID and required fields, and send the resulting entity. Do not assume Set is a JSON Patch operation.
  • Use stable external references or other documented unique values to detect an existing entity before retrying Add. A network failure can leave the client uncertain whether a mutation completed.
  • Treat Remove as destructive and irreversible unless the entity documentation provides a recovery lifecycle. Its entity argument is not a filter. Prefer a documented archive or deactivation lifecycle when the business object supports one.
  • When the entity supports it, read after a critical write and verify the intended state before recording the workflow as complete. Account for documented consistency behavior while verifying.

Do not place mutations in ExecuteMultiCall. MultiCall is not transactional: earlier calls remain committed when a later call fails, and calls after the failure are not run.

Handling failures

Classify the failure before retrying. Retrying every error can amplify an outage, duplicate writes, or hide a permission problem.

FailureResponse
HTTP 429, an over-limit response, a temporary server failure, or a network timeout during a safe, idempotent requestRetry a bounded number of times with exponential backoff and jitter. Honor Retry-After when present and reduce request concurrency or volume. For a mutation or any request that might have been accepted, reconcile the target state before deciding whether to retry.
Invalid or expired sessionRefresh or authenticate once, then retry the original request once.
Missing method, invalid argument, unsupported entity, duplicate, or insufficient clearanceDo not retry unchanged. Correct the request, feature expectation, or access configuration.
Timeout after a mutation was sentRead the target state or query by its unique reference before deciding whether to retry.

Record the method, entity type, database alias, duration, retry count, HTTP status, JSON-RPC error type, and the server-provided error ID. For MultiCall, also record requestIndex. Redact credentials and customer payloads. Monitor rate-limit responses, feed backlog, checkpoint age, processing failures, and the time of the last successful call.

Generic messages such as Object reference not setcan result from a missing required parameter, an invalid referenced ID, or a referenced entity that is outside the user's scope. Validate those conditions first. If the request is valid, include the server-provided error ID when escalating the response as a possible server defect.

Reviewing before production
  • Run with the production service account's clearances and data scope in a test database.
  • Test empty, single-result, ambiguous, maximum-page, and multi-page responses.
  • Stop the process between committing a feed batch and saving its checkpoint; confirm that replay does not duplicate outcomes.
  • Inject a 429, expired session, timeout, malformed request, and failed nested MultiCall.
  • Measure realistic response sizes and latency with and without PropertySelector.
  • Verify that mutations are blocked from the wrong database and that uncertain outcomes are reconciled before retry.
  • Track the MyGeotab release notes and update API client packages regularly.