Authentication & Tokens

What is the difference between a refresh token and an access token?

The Hawkin Dynamics API uses a two-token authentication flow. Your refresh token (also called your Integration Key) is a long-lived secret you generate once in the Hawkin dashboard. You exchange it for a short-lived access token by calling /api/token. The access token is what you include as a Bearer token in all subsequent API requests.

Each integration handles this exchange automatically: R uses get_access(), Python uses AuthManager(), and Power Query uses funcAuth().

How long does an access token last?

Access tokens expire after 1 hour. After expiration, you must request a new one by calling /api/token with your refresh token again. The R and Python packages handle re-authentication automatically. In Power Query, the epochNow() function validates token freshness internally.

What do 401 and 403 errors mean?

A 401 Unauthorized response means your access token is invalid or has expired — request a new one from /api/token. A 403 Forbidden response on the token endpoint means your refresh token is missing from the request. Verify that your refresh token is included in the Authorization: Bearer header.

How do I choose the correct regional endpoint?

Your region must match where your organization's data is hosted:

  • Americas: cloud.hawkindynamics.com
  • Europe: eu.cloud.hawkindynamics.com
  • Asia-Pacific: apac.cloud.hawkindynamics.com

Using the wrong region will result in authentication failures. In R, pass the region parameter to get_access(). In Python, pass it to AuthManager(). In Power Query, set the reg parameter.

Where do I find my Integration Key (refresh token)?

Log into your Hawkin Dynamics account and navigate to Settings → Integrations. Only organization administrators can generate API tokens. If you do not see the Integrations option, contact your organization's admin.

How should I store my refresh token securely?

Never hardcode your refresh token in source files or share it publicly. In Python, store it as the HD_REFRESH_TOKEN environment variable or in a .env file. In R, use an .Renviron file. In Power Query, use Power BI Parameters (which are not exposed in published reports). For deployed apps, use the hosting platform's environment variable settings.

Test Data & Filtering

What is the difference between from/to and syncFrom/syncTo?

These serve different use cases. Use from/to for historical bulk exports — they filter tests by their original creation timestamp. Use syncFrom/syncTo for incremental syncing in scheduled jobs — they return tests that have been created or modified since the given timestamp, catching retroactive edits and new data.

Store the lastSyncTime value from each response and pass it as syncFrom in your next request.

Can I combine syncFrom/syncTo with athlete, team, or group filters?

No. The syncFrom/syncTo parameters cannot be combined with athleteId, teamId, groupId, or testTypeId filters. These filters only work with from/to date parameters. If you need filtered incremental sync, pull all synced data first and filter client-side.

What happens if I call the tests endpoint with no parameters?

The API returns every test in your organization's database. For large organizations, this can be an enormous response that exceeds memory limits and fails. Always include date parameters (from/to or syncFrom/syncTo) to limit response size.

Why do some metric values show "N/A" instead of a number?

Some metrics return the string "N/A" when the value could not be calculated for a particular test trial. Your code should handle this case explicitly — do not assume all metric values are numeric. Check for "N/A" before performing calculations or type conversions.

Should I hardcode metric column names in my code?

No. Metric names and availability are dynamic and can change as Hawkin Dynamics updates its platform. New metrics may appear at any time, and some may be absent for certain tests. Use get_metrics() (R), GetMetrics() (Python), or the /api/v1/metrics endpoint to retrieve the current list programmatically.

What are lastSyncTime, lastTestTime, and count in the response?

These are top-level metadata fields in every test response. count is the number of tests returned. lastTestTime is the timestamp of the most recent test in the results. lastSyncTime is the timestamp you should store and pass as syncFrom in your next incremental sync request to avoid re-fetching data.

Platform-Specific Issues

How do I install the R package (hawkinR)?

The hawkinR package is installed from GitHub using devtools, not from CRAN:

devtools::install_github("HawkinDynamics/hawkinR")

You need the devtools package installed first (install.packages("devtools")).

How do I install the Python package (hdforce)?

The hdforce package is available on PyPI:

pip install hdforce

In Power Query, why are my metric columns showing as Text type?

Power Query may default dynamically generated columns to Text type. The Parameterized Template and Template Files automatically type metric columns as numbers, but if you are using Generic scripts, you may need to set types manually. In Power Query Editor, select the metric columns and use Transform → Detect Data Type, or explicitly cast them in the Applied Steps.

What is the difference between Generic and Parameterized Power Query scripts?

Generic scripts are self-contained — paste one into the Advanced Editor and run. They make a single API call, which is simpler but may timeout for large date ranges. Parameterized templates use shared functions and Power BI Parameters, automatically split requests into 30-day chunks, and reuse a cached auth token. Use Parameterized for production dashboards with significant data.

My Power Query refresh is timing out. What should I do?

If you are using a Generic script, switch to the Parameterized Template, which automatically chunks requests into 30-day windows. Also verify your date range is not unnecessarily wide. For very large organizations, consider narrowing your date range or filtering by specific test types. You can download the Parameterized scripts from the Power Query documentation Downloads tab.

Why are my athlete external properties disappearing after an update?

When you update an athlete using the PUT endpoint, the external properties object is replaced entirely, not merged. Any custom properties you omit from the request body will be permanently removed. Always include every external property you want to keep in each update request.

General / Getting Started

Which integration should I use?

It depends on your workflow:

  • R (hawkinR) — Best for statistical analysis, sport science research, and ad-hoc exploration in RStudio
  • Python (hdforce) — Best for data pipelines, automation, and integration with machine learning or data science workflows
  • Power Query — Best for Power BI dashboards and Excel-based reporting without writing code
  • Direct API — Best for custom applications, server-to-server integrations, and languages not covered above
How do I get force-time (raw waveform) data?

Force-time data is retrieved per individual test, not in bulk. First, query the tests endpoint to get test IDs, then call /api/v1/forcetime/{test_id} with a specific test ID. In R, use get_forcetime(testId). In Python, use GetForceTime(testId). The data is returned as time-series arrays sampled at 1000 Hz.

Is there a limit on how many athletes I can create or update at once?

Yes. The bulk create and bulk update endpoints accept a maximum of 500 athletes per request. Exceeding this limit returns a 413 Payload Too Large error. If you need to process more, split your data into batches of 500.

Can I filter tests by multiple teams or groups at once?

Yes. The teamId and groupId parameters accept comma-separated lists of up to 10 IDs each (e.g., teamId=idA,idB,idC). These filters only work with the from/to date parameters, not with syncFrom/syncTo.

Where can I get help if my question isn't answered here?

Contact Hawkin Dynamics technical support at dev-team@hawkindynamics.com or call 207-405-9142. For package-specific issues, you can also file issues on GitHub: hawkinR and hawkinPy.