The FulcraAPI class
Bases: FulcraDataAccessMixin
The main class for making Fulcra API functions.
This contains functions for authorizing a token, authenticating HTTP requests, making calls, and loading data.
__init__(oidc_domain=None, oidc_client_id=None, oidc_scope=None, oidc_audience=None, access_token=None, access_token_expiration=None, refresh_token=None, credentials=None, refresh_callback=None)
Initializes the FulcraAPI client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
oidc_domain
|
Optional[str]
|
Optional. The OIDC provider domain to use for authentication. Defaults to FULCRA_OIDC_DOMAIN. |
None
|
oidc_client_id
|
Optional[str]
|
Optional. The OIDC client ID to use. Defaults to FULCRA_OIDC_CLIENT_ID. |
None
|
oidc_scope
|
Optional[str]
|
Optional. The OAuth scopes to request. Defaults to FULCRA_OIDC_SCOPE. |
None
|
oidc_audience
|
Optional[str]
|
Optional. The OIDC audience for the token. Defaults to FULCRA_OIDC_AUDIENCE. |
None
|
access_token
|
Optional[str]
|
Optional. An existing access token to use. [Deprecated] |
None
|
access_token_expiration
|
Optional[datetime]
|
Optional. The expiration datetime for the provided access_token. [Deprecated] |
None
|
refresh_token
|
Optional[str]
|
Optional. An existing refresh token to use. [Deprecated] |
None
|
credentials
|
Optional[FulcraCredentials]
|
Optional. A FulcraCredentials object with credentials to use. |
None
|
refresh_callback
|
Optional[Callable]
|
Optional. A callback function for when the access token is successfully refreshed. |
None
|
annotations_catalog(fulcra_userid=None)
Retrieves a list of all annotations the user has defined, whether or not there is any data in them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of defined annotations, including data about type and ID. Use this |
List[Dict]
|
information with the annotation-retrieval functions |
List[Dict]
|
( |
List[Dict]
|
data for a time window. |
Examples:
>>> annotations = fulcra.annotations_catalog()
>>> annotations[3]
{'name': 'Energy Level', 'description': 'How much energy do I have right now?', 'annotation_type': 'scale', 'measurement_spec': {'value_type': 'integer', 'metric_kind': 'discrete', 'measurement_type': 'scale', 'unit': None, 'scale': {'min_allowed': 1, 'max_allowed': 5, 'value': 3}}, 'spec': {'default_note': None, 'scale': {'label_mapping': {'mapping_type': 'string', 'string': {'mapping': {'1': 'Very Low', '2': 'Low', '3': 'Medium', '4': 'High', '5': 'Very High'}}}, 'scale_mapping': {'mapping_type': 'emoji', 'color': {'mapping': {'1': '#ff3b30', '2': '#ff9e96', '3': '#8a8a8f', '4': '#99e3ab', '5': '#33c759'}}, 'string': {'mapping': {'1': 'annotation-emoji-1', '2': 'annotation-emoji-2', '3': 'annotation-emoji-3', '4': 'annotation-emoji-4', '5': 'annotation-emoji-5'}}}}}, 'tags': ['cb8e9254-1446-4055-9e3c-4d76335d1be5'], 'fulcra_userid': '315c1b32-5399-40e1-b808-2346da7bf32e', 'id': 'a6b01642-2298-4a49-af6f-0e7edf1cb3cb', 'created_at': '2025-05-22T20:40:51.191044Z', 'updated_at': '2025-05-22T20:40:51.191044Z', 'deleted_at': '2025-05-24T21:52:29.985758Z'}
apple_location_updates(start_time, end_time, fulcra_userid=None)
Retrieve the raw Apple location update samples during the specified period of time.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a location update. |
Examples:
To retrieve all location updates within a specific hour:
>>> updates = fulcra.apple_location_updates(
... start_time="2023-09-24T20:00:00Z",
... end_time="2023-09-24T21:10:00Z"
... )
To see the details of the first update:
>>> updates[0]
{'speed': -1, 'horizontal_accuracy_meters': 35, 'longitude_degrees':
-117.15661336566698, 'source_is_simulated_by_software': False,
'source_is_produced_by_accessory': False, 'latitude_degrees':
32.706505158026005, 'vertical_accuracy_meters': 3.0130748748779297,
'course_heading_accuracy_degrees': -1, 'course_heading_degrees': -1,
'ellipsoidal_altitude_meters': -6.280021667480469, 'floor': 0,
'speed_accuracy_meters': -1, 'altitude_meters': 29.17388153076172, 'uuid':
'e80feacc-54e9-414f-86cb-8d6ebd85ea41', 'timestamp':
'2023-09-24T20:39:28.056+00:00'}
apple_location_visits(start_time, end_time, fulcra_userid=None)
Retrieve the raw Apple location visit samples during the specified period of time.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a location visit. |
Examples:
To retrieve all location updates within a specific hour:
>>> visits = fulcra.apple_location_visits(
... start_time="2023-09-24T20:00:00Z",
... end_time="2023-09-24T21:10:00Z"
... )
To see the details of the first update:
>>> visits[0]
{'longitude_degrees': -117.1224047932943, 'latitude_degrees':
32.75812770726706, 'arrival_date': '0001-01-01T00:00:00+00:00',
'departure_date': '2023-09-25T01:42:16.998+00:00',
'horizontal_accuracy_meters': 32.93262639589646, 'uuid':
'935971dd-0822-49ef-a74f-b09a24d68c3a'}
apple_workouts(start_time, end_time, fulcra_userid=None)
Retrieve the list of Apple workouts that occurred (at least partially) during the specified time range.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a workout. |
Examples:
To retrieve all workouts during a time period:
>>> workouts = fulcra.apple_workouts(
... start_time = "2023-09-21 07:00:00.000Z",
... end_time = "2023-09-22 07:00:00.000Z"
... )
To inspect the details of a workout:
>>> workouts[0]
{'start_date': '2023-09-21T19:18:31.733000Z', 'end_date':
'2023-09-21T19:49:08.773000Z', 'has_undetermined_duration': False,
'apple_workout_id': '480b25fe-b229-41b9-bf13-7ccf5e2092ec', 'duration':
1837.0397539138794, 'extras': {'HKTimeZone': 'America/Los_Angeles',
'HKAverageMETs': '4.37848 kcal/hr·kg' ... }
authorize()
Request a device token, then prompt the user to authorize it.
This uses the Device Authorization workflow, which requires the user to visit a link and confirm that the code shown on the screen matches.
This function will attempt to open the link in a new browwser tab (using
webbrowser module); it will also be either print()ed out (or display()ed
out if run inside Jupyter).
The function will wait until the user visits the page and authentiactes, or until a specified time has passed.
Raises an exception on failure.
Examples:
fulcra.authorize() Use your browser to log in to Fulcra. If the tab does not open automatically, visit this URL to authenticate: https://fulcra.us.auth0.com/activate?user_code=SJZC-GRBW
When the authorization succeeds, the following will be displayed:
Authorization succeeded.
authorize_with_authorization_code(code, redirect_uri)
Exchanges an authorization code for an access token, refresh token, and ID token.
This method should be called after the user has been redirected back
to your application's redirect_uri with an authorization code.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
code
|
str
|
The authorization code received from Auth0. |
required |
redirect_uri
|
str
|
The same |
required |
Raises:
| Type | Description |
|---|---|
Exception
|
If the token exchange fails. |
boolean_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Boolean Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
calendar_events(start_time, end_time, calendar_ids=None, fulcra_userid=None)
Retrieve the list of calendar events that occur (at least partially) during the specified time range.
To request events from another user's store, pass their user
ID as the fulcra_userid parameter.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
calendar_ids
|
Optional[List[str]]
|
If included, the query results are limited to events that are on the specified calendars. |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a calendar event. |
Examples:
To retrieve all calendar events that span a given range of time:
>>> cal_events = fulcra.calendar_events(
... start_time = "2023-09-24 07:00:00.000Z",
... end_time = "2023-09-25 07:00:00.000Z",
... calendar_ids=["01fb4138-db27-4792-867d-5cfbdc720165"]
... )
To inspect the details of an event:
>>> cal_events[0]
{'calendar_event_id': 'c409a249-24cd-4c19-b763-3683cc21b9f8',
'calendar_id': '01fb4138-db27-4792-867d-5cfbdc720165', 'start_date':
'2023-09-24T20:10:00Z', 'end_date': '2023-09-24T21:10:00Z',
'allow_new_time_proposals': None, 'alarms':
['19b7692e-7434-44be-a5ba-c8dfa338deb6'], 'availability': 'free',
'calendar_item_external_identifier':
'7kukuqrfedlm2f9tfbe684r6cqpk9mrk0aqdeoan7jdbr93e7963lagn9uq6pdsbac40',
'calendar_item_identifier': '22153B27-4BEE-480C-9627-F2EABC698103',
'event_identifier':
'EC9D6240-04A7-4869-9D2E-1A7648EA7732:7kukuqrfedlm2f9tfbe684r6cqpk9mrk0aqdeoan7jdbr93e7963lagn9uq6pdsbac40',
'creation_date': '2023-09-16T23:27:22Z', 'has_alarms': True,
'has_attendees': True, 'has_notes': True, 'has_recurrence_rules':
False, 'is_all_day': False, 'is_detached': False, 'last_modified_date':
'2023-09-16T23:27:26Z', 'location': 'PETCO Park', 'notes':
'This event was created from an email you received in Gmail.',
'occurrence_date': '2023-09-24T20:10:00Z', 'organizer':
'22381502-0af3-487a-820c-e22aa4cae201', 'recurrence_rules': None,
'status': 'confirmed', 'geolocation': None, 'time_zone':
'America/Los_Angeles (fixed)', 'title':
'St. Louis Cardinals at San Diego Padres', 'url': None,
'extras': {}, 'participants': [{'is_current_user': True,
'participant_role': 'required', 'participant_type': 'person',
'participant_status': 'accepted', 'url': 'mailto:cstone@gmail.com',
'contact_id': '00900185-b290-4f1c-860d-e4433024a943',
'name': 'cstone@gmail.com'}]}
calendars(fulcra_userid=None)
Retrieve the list of calendars available in your data store.
To request the calendars from another user's store, pass their user
ID as the fulcra_userid parameter.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which represents a calendar. |
Examples:
To retrieve all calendars from your data store:
>>> calendars = fulcra.calendars()
>>>
To inspect the details of a calendar:
>>> calendars[0]
{'calendar_id': '02b761da-46d0-4074-a9c8-406fd0de3adf', 'calendar_name':
'Birthdays', 'calendar_color':
'[0.5098039507865906,0.5843137502670288,0.686274528503418,1.0]',
'calendar_source_id': '03da9f61-7b58-4021-8f40-a93548258faf',
'calendar_source_name': 'Other', 'fulcra_source': 'apple_calendar'}
create_datashare(datashare_name, fulcra_data_types, allowed_user_ids=None, share_all_data=False, time_start=None, time_end=None, allowed_group_ids=None)
Creates a new datashare to share your data with other users.
A datashare can name individual users (allowed_user_ids), whole data
groups (allowed_group_ids), or both. Sharing with a group grants
access to everyone who is currently a participant in it: members who
join later gain access, and members who leave lose it. You do not
have to own a group to share your data into it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datashare_name
|
str
|
Name for this datashare |
required |
fulcra_data_types
|
List[str]
|
List of data type IDs to share |
required |
allowed_user_ids
|
Optional[List[str]]
|
List of Fulcra user IDs to share with |
None
|
share_all_data
|
bool
|
Whether to share all data types (default: False) |
False
|
time_start
|
Optional[str | datetime]
|
Optional start of the shared range, as an ISO 8601
string or |
None
|
time_end
|
Optional[str | datetime]
|
Optional end of the shared range, as an ISO 8601 string
or |
None
|
allowed_group_ids
|
Optional[List[str]]
|
List of group UUIDs to share with. Every group must exist; if any does not, the server rejects the whole request and no datashare is created. |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
A dict containing the created datashare information. |
Examples:
>>> datashare = fulcra_client.create_datashare(
... datashare_name="My Research Share",
... fulcra_data_types=["HeartRate", "StepCount"],
... allowed_user_ids=["a24a9667-c2c6-4bbf-9a0f-4Bej0afcb521"]
... )
To share with everyone in a group instead:
>>> datashare = fulcra_client.create_datashare(
... datashare_name="Step Challenge Share",
... fulcra_data_types=["StepCount"],
... allowed_group_ids=["cf362f80-ef41-4c08-b5e3-b18bd3d1524b"],
... )
create_group(title, responsible_entity, description, *, fulcra_data_types=None, group_url=None, time_start=None, time_end=None, detail_markdown=None, agreement_markdown=None, withdraw_markdown=None, header_image_url=None, preview_image_url=None, friendly_id=None)
Creates a new data group that other Fulcra users can join.
When a participant joins the group, they share read-only access to
their data (limited to fulcra_data_types and the given time range)
with you until they leave the group.
Most group parameters are immutable after creation; for example, the group owner can't later change the conditions of the data you agreed to share when you join.
A group does not have to collect anything. Omit fulcra_data_types
and joining shares no data at all, which makes the group a pure
audience: other users can share their own data with everyone in it by
naming it in allowed_group_ids on create_datashare. Since the
group's data types are immutable too, such a group can never start
collecting data later.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title
|
str
|
Title of the group |
required |
responsible_entity
|
str
|
The person or organization responsible for the group |
required |
description
|
str
|
Description of the group |
required |
fulcra_data_types
|
Optional[List[str]]
|
Optional list of Fulcra data types that participants will share. When omitted, participants share nothing. |
None
|
group_url
|
Optional[str]
|
Optional URL of the webapp associated with this group |
None
|
time_start
|
Optional[str | datetime]
|
Optional start of the shared data time range, as an
ISO 8601 string or |
None
|
time_end
|
Optional[str | datetime]
|
Optional end of the shared data time range, as an ISO
8601 string or |
None
|
detail_markdown
|
Optional[str]
|
Optional markdown shown on the group's detail view |
None
|
agreement_markdown
|
Optional[str]
|
Optional markdown shown when a user joins |
None
|
withdraw_markdown
|
Optional[str]
|
Optional markdown shown when a user leaves |
None
|
header_image_url
|
Optional[str]
|
Optional URL of the group's header image |
None
|
preview_image_url
|
Optional[str]
|
Optional URL of the group's preview image |
None
|
friendly_id
|
Optional[str]
|
Optional human-friendly identifier for the group |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
The created group, represented by a dict. |
Examples:
>>> group = fulcra_client.create_group(
... title="Step Challenge",
... responsible_entity="Fulcra Dynamics",
... description="A month-long step challenge.",
... fulcra_data_types=["StepCount"],
... group_url="https://example.com/challenge",
... )
A group that collects nothing, to share data into later:
>>> group = fulcra_client.create_group(
... title="Research Cohort",
... responsible_entity="Fulcra Dynamics",
... description="Members receive data shared with them.",
... )
>>> group["fulcra_data_types"]
[]
create_tag(tag_name)
Creates a user defined tag.
Requires a valid access token.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
The created tag; represented by a dict. |
create_tags(tag_names)
Creates a batch of user defined tags.
If a tag already exist, the existing tag is returned.
Requires a valid access token.
Returns:
| Type | Description |
|---|---|
list[dict[str, str]]
|
The created tag; represented by a dict. |
data_updates(start_time, end_time, fulcra_userid=None)
Retrieve a summary of the data that was updated during the specified time range for the authenticated user.
This reports the data types that had records processed during the range (along with the number of records processed for each), as well as any uploaded files that changed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
str | datetime
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
str | datetime
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
str | None
|
Optional Fulcra user ID to get updates for |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
A dict with two keys: |
dict
|
|
dict
|
|
Examples:
To see what data was updated during a given range:
>>> updates = fulcra.data_updates(
... start_time="2026-02-01 00:00:00Z",
... end_time="2026-02-03 00:00:00Z"
... )
>>> updates["data_types"]
{'StepCount': 412, 'HeartRate': 1875}
delete_annotation(annotation_id)
Soft-deletes a user-defined annotation by ID.
Requires a valid access token.
delete_dataset_permission(grant_id)
Gives up your access to a dataset that was shared with you.
Which grants you may remove depends on the grant's grant_type, as
reported by get_shared_datasets:
- A
usergrant may be removed by the person it was granted to. - A
groupgrant may only be removed by the person who created the datashare, since it confers access on everyone in the group. If you reach a dataset through a group and want out, useleave_groupinstead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grant_id
|
str
|
The |
required |
Examples:
>>> fulcra_client.delete_dataset_permission("cf362f80-ef41-4c08-b5e3-b18bd3d1524b")
delete_datashare(datashare_id)
Deletes a datashare that you created, revoking every grant it confers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datashare_id
|
str
|
UUID of the datashare to delete |
required |
Examples:
>>> fulcra_client.delete_datashare("cf362f80-ef41-4c08-b5e3-b18bd3d1524b")
delete_group(group_id)
Deletes a group that you own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group to delete |
required |
delete_tag(tag_id)
Soft-deletes a user-defined tag by ID.
Requires a valid access token.
download_file(file_id, fulcra_userid=None)
download a file and return the file object
duration_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Duration Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
fulcra_api(url_path, method='GET', query=None, data=None, return_http_response=False, content_type='application/json', authenticated=True)
Make a call to the given url path (e.g. /v0/data/metric_time_series?...)
with the specified access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url_path
|
str
|
The path of the URL to use (e.g. |
required |
method
|
str
|
The HTTP method for the request (Default: GET) |
'GET'
|
query
|
dict[str, str] | None
|
Key/value pairs of query params |
None
|
data
|
dict | List[dict] | None
|
Dictionary or list of dictionaries to send as request body |
None
|
return_http_response
|
bool
|
Return a HTTPResponse object instead of bytes (default: False) |
False
|
content_type
|
str
|
Content-Type header (default: "application/json") |
'application/json'
|
authenticated
|
bool
|
When False, make the request without credentials. Only valid for public endpoints. (default: True) |
True
|
Returns:
| Type | Description |
|---|---|
bytes | HTTPResponse
|
The raw response data (as bytes). Raises an exception on failure. |
fulcra_v1_records(query, fulcra_userid=None)
Query v1 data-type records using a PromQL query.
The data type, time window, and any filters are all expressed inside the
PromQL query string (e.g. "HeartRate[1h] @ 1717200000").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
The PromQL query. |
required |
fulcra_userid
|
Optional[str]
|
Query another user's data (requires an active datashare from that user). |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The raw response data (as bytes), in JSONL form (one JSON record per |
bytes
|
line). Raises an exception on failure. |
fulcra_v1alpha1_api(data_class, data_type, params=None)
Make a call to the v1alpha1 API.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
access_token
|
The access token to authenticate the request with |
required | |
data_class
|
str
|
The class of data to query (event or metric) |
required |
data_type
|
str
|
The data type to query |
required |
params
|
Optional[dict]
|
Additional params to add to the query |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The raw response data (as bytes). Raises an exception on failure. |
fulcra_v1alpha1_api_path(path, params=None)
Make a call to the v1alpha1 API using a full path.
Supports annotation shorthands with UUIDs (e.g., "metric/MomentAnnotation/
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
The full path after /data/v1alpha1/ (e.g., "event/MomentAnnotation" or "metric/NumericAnnotation/ |
required |
params
|
Optional[dict[str, str]]
|
Additional params to add to the query |
None
|
Returns:
| Type | Description |
|---|---|
bytes
|
The raw response data (as bytes). Raises an exception on failure. |
get_authenticated_user_email()
Retrieve the email address of the currently authorized user.
The email is read from the email claim of the ID token.
Returns:
| Type | Description |
|---|---|
Optional[str]
|
The authenticated user's email, or None if the ID token has no email |
Optional[str]
|
claim. |
get_authenticated_user_name()
Retrieve the display name of the currently authorized user.
The name is read from the name claim of the ID token.
Returns:
| Type | Description |
|---|---|
Optional[str]
|
The authenticated user's name, or None if the ID token has no name |
Optional[str]
|
claim. |
get_authorization_code_url(redirect_uri, state=None)
Generates the URL to redirect the user to for the Authorization Code Grant flow.
The calling application (e.g., a web service) should redirect the user
to this URL. After the user authenticates and authorizes the application,
Auth0 will redirect the user back to the specified redirect_uri with
an authorization code (and state if provided) in the query parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
redirect_uri
|
str
|
The URL where the user will be redirected after authorization. This must be registered in your Auth0 application settings. |
required |
state
|
Optional[str]
|
An opaque value used to maintain state between the request and the callback. It's also used to prevent CSRF attacks. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The authorization URL. |
get_cached_access_token()
Deprecated. Return access token from current credentials.
get_cached_access_token_expiration()
Deprecated. Return access token expiration from credentials
get_cached_refresh_token()
Deprecated. Return refresh token from current credentials
get_datashare(datashare_id)
Retrieves a single datashare that you created.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datashare_id
|
str
|
UUID of the datashare |
required |
Returns:
| Type | Description |
|---|---|
dict
|
The datashare, represented by a dict. |
Examples:
>>> share = fulcra_client.get_datashare(
... "cf362f80-ef41-4c08-b5e3-b18bd3d1524b"
... )
>>> share["group_permissions"]
[{'allowed_group_id': '...'}]
get_datashares()
Retrieves all datashares created by the authenticated user.
Returns a list of datashares that you have created to share your data
with others. Each one lists its individual recipients under
permissions and the groups it is shared with under
group_permissions.
Returns:
| Type | Description |
|---|---|
List[dict]
|
A list of datashare dicts. |
Examples:
>>> datashares = fulcra_client.get_datashares()
>>> datashares[0]
{'datashare_id': '...', 'datashare_name': 'My Share', ...}
get_fulcra_userid()
Retrieve the currently authorized Fulcra UserID.
Returns:
| Type | Description |
|---|---|
str
|
the Fulcra UserID of the currently-authorized user. |
get_group(group_id)
Retrieves the description of a single data group.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group |
required |
Returns:
| Type | Description |
|---|---|
dict
|
The group, represented by a dict. |
get_group_jwks()
Retrieves the group public keys as a JWKS.
Group webapps can use these keys to validate the participant JWTs that Context sends when authenticating requests.
Requires a valid access token. (The underlying route defines no authentication requirement, but the API gateway currently rejects unauthenticated requests.)
Returns:
| Type | Description |
|---|---|
dict
|
The JWKS, represented by a dict. |
get_group_participant_metadata(group_id, participant_id)
Retrieves the metadata object for a participant in a group you own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group |
required |
participant_id
|
str
|
Participant ID within the group |
required |
Returns:
| Type | Description |
|---|---|
dict
|
The participant's metadata, represented by a dict. |
get_group_participants(group_id)
Retrieves the participant IDs of a group that you own.
Participant IDs are anonymized UUIDs that are only meaningful within this group; they do not reveal participants' Fulcra UserIDs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group |
required |
Returns:
| Type | Description |
|---|---|
List[str]
|
A list of participant ID strings. |
get_groups(subscribed_only=False)
Retrieves a list of data groups.
By default, returns all public groups plus every group you own,
public or not. When subscribed_only is True, returns only the
groups that you have joined; each of these also includes your
participant_id and joined_at values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
subscribed_only
|
bool
|
When True, return only groups you have joined (default: False) |
False
|
Returns:
| Type | Description |
|---|---|
List[dict]
|
A list of groups; each is represented by a dict. |
Examples:
>>> groups = fulcra_client.get_groups(subscribed_only=True)
>>> groups[0]["title"]
'My Research Study'
get_id_token_claims()
Decode and return all claims from the ID token.
Returns:
| Type | Description |
|---|---|
dict
|
A dict containing all JWT claims from the ID token. |
get_shared_datasets()
Retrieves the datasets that the authenticated user can read.
There is one entry per grant, and grant_type says where each one
comes from:
self: your own data. Always the first entry, and the only one with a nullgrant_idanddatashare_id.user: a datashare somebody granted to you directly.group: a datashare granted to a data group you participate in;group_idnames the group.
Because the two kinds of grant are independent, someone who holds both
a direct grant and a group grant on the same datashare gets two
entries: they carry the same datashare_id and differ in
grant_type. The sharer is identified by sharing_fulcra_userid.
Pass an entry's grant_id to delete_dataset_permission to give up
that access; see that method for which grants you are allowed to
remove.
Examples:
>>> datasets = fulcra_client.get_shared_datasets()
>>> [d["grant_type"] for d in datasets]
['self', 'user', 'group']
>>> datasets[2]["group_id"]
'cf362f80-ef41-4c08-b5e3-b18bd3d1524b'
get_tag_by_id(tag_id)
Retrieves a user defined tag by ID.
Requires a valid access token.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A user-defined tag represented by a dict. |
get_tag_by_name(name)
Retrieves a user defined tag by name.
Requires a valid access token.
Returns:
| Type | Description |
|---|---|
dict[str, str]
|
A user-defined tag represented by a dict. |
get_token(device_code)
Deprecated. Polls for an access token using a device code. Used by the device authorization flow.
get_token_claims()
Decode and return all claims from the access token.
Returns:
| Type | Description |
|---|---|
dict
|
A dict containing all JWT claims from the access token. |
get_user_info()
Return information about the authenticated Fulcra User.
Returns information about the authenticated Fulcra User, including their preferences such as time zone, calendar ids, etc.
Returns:
| Type | Description |
|---|---|
Dict
|
A dict containing user information. |
Examples:
>>> user_info = fulcra_client.get_user_info()
>>> user_info
{'userid': 'a24a9667-c2c6-4bbf-9a0f-4Bej0afcb521', 'created': '2024-08-20T19:51:09.123456Z', 'preferences': {'timezone': 'America/Los_Angeles'}}
gmaps_location_updates(start_time, end_time, fulcra_source_id=None, fulcra_userid=None)
Return Google Maps geo-location update samples for a user.
Retrieve the raw Google Maps location update samples for the specified user during the specified period of time.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO 8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO 8601 format (exclusive). |
required |
fulcra_source_id
|
Optional[str]
|
Optional. When present, specifies the Fulcra source ID to filter results. |
None
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a Google Maps location update. |
group_participant(group_id, participant_id)
Returns an accessor for the data that a group participant shares with you.
The returned object has the same data-access methods as this client
(metric_time_series, metric_samples, sleep_agg, ...), scoped to
the participant's shared data, along with the participant metadata
operations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of a group that you own |
required |
participant_id
|
str
|
Participant ID within the group |
required |
Returns:
| Type | Description |
|---|---|
FulcraGroupParticipant
|
A |
Examples:
>>> for pid in fulcra_client.get_group_participants(group_id):
... participant = fulcra_client.group_participant(group_id, pid)
... df = participant.metric_time_series(
... start_time="2026-07-01T00:00:00Z",
... end_time="2026-07-02T00:00:00Z",
... metric="StepCount",
... )
join_group(group_id)
Joins a data group as a participant.
Joining shares read-only access to your data (limited to the group's
data types and time range) with the group's owner until you leave.
The owner sees you only as the returned anonymized participant_id,
never your Fulcra UserID.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group to join |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A dict containing the |
dict
|
|
leave_group(group_id)
Leaves a data group, revoking the owner's access to your data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group to leave |
required |
list_shared_data_types(fulcra_userid, start_time, end_time)
Summarizes what another user has shared with you over a time range.
Use this before querying someone else's data, rather than discovering the boundaries of your access by being denied.
A share counts toward the answer only if it fully covers the
requested window, and the end of the window is compared strictly
(end_time < time_end) -- so asking for exactly a share's declared
range reports nothing, and you should ask about a window strictly
inside it. Access granted through a data group counts the same as a
direct grant, so the answer changes as you join and leave groups.
Having nothing shared with you is a normal answer, not an error: you
get all_data_types False and an empty list. Asking about yourself
always reports all_data_types True.
Shared file paths are not reported here, and the legacy input:custom
type is omitted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fulcra_userid
|
str
|
The Fulcra UserID of the person sharing with you |
required |
start_time
|
str | datetime
|
The start of the range (inclusive), as an ISO 8601
string or |
required |
end_time
|
str | datetime
|
The end of the range (exclusive), as an ISO 8601 string
or |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A dict with two keys: |
dict
|
|
dict
|
|
Examples:
>>> allowed = fulcra_client.list_shared_data_types(
... "a24a9667-c2c6-4bbf-9a0f-4bef0afcb521",
... start_time="2026-08-01T00:00:00Z",
... end_time="2026-08-08T00:00:00Z",
... )
>>> allowed
{'all_data_types': False, 'fulcra_data_types': ['HeartRate', 'StepCount']}
location_at_time(time, window_size=14400, include_after=False, reverse_geocode=False, fulcra_userid=None)
Gets the user's location at the specified time. If no sample is
available for the exact time, searches for the closest sample up to
window_size seconds back. If include_after is true, then also
searches window_size seconds forward.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time
|
Union[str, datetime]
|
The point in time to get the user's location for. |
required |
window_size
|
int
|
The size (in seconds) to look back (and optionally forward) for samples |
14400
|
include_after
|
bool
|
When true, a sample that occurs after the requested time may be returned if it is the closest one. |
False
|
reverse_geocode
|
bool
|
When true, Fulcra will attempt to reverse geocode the location and include the details in the results. |
False
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts; the first dict is the best location sample. |
Examples:
location = fulcra.location_at_time( ... time = "2024-01-24 00:00:00-08:00", ... )
location [{'speed': 0, 'horizontal_accuracy_meters': 4.848857421534995, 'longitude_degrees': -117.15709954484828, 'latitude_degrees': 32.707083bb994486, 'vertical_accuracy_meters': 3.2114044806616686, 'course_heading_accuracy_degrees': 180, 'course_heading_degrees': 87.05299950647989, 'ellipsoidal_altitude_meters': 32.700060645118356, 'floor': 0, 'speed_accuracy_meters': 0.9654413396512306, 'altitude_meters': 6.15396384336054, 'uuid': '59b2d63b-9b0b-436f-a66f-01129e1b33dd', 'timestamp': '2024-01-24T00:01:45.941+00:00', 'location_source': 'apple_location_update'}]
location_time_series(start_time, end_time, change_meters=None, sample_rate=900, look_back=14400, reverse_geocode=False, fulcra_userid=None)
Retrieve a time series of locations that the user was at. This uses the most precise underlying data sources available at the given time.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
change_meters
|
Optional[float]
|
when specified, subsequent samples that are fewer than this many meters away will not be included. |
None
|
sample_rate
|
int
|
The length (in seconds) of each sample |
900
|
look_back
|
int
|
The maximum number of seconds in the past to look back to find a value for a sample. |
14400
|
reverse_geocode
|
bool
|
When true, Fulcra will attempt to reverse geocode the locations and include the details in the results. |
False
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of samples; each sample represents a location sample. |
Examples:
>>> locations = fulcra.location_time_series(
... start_time = "2024-06-06T19:00:00-07:00",
... end_time = "2024-06-06T20:00:00-07:00",
... reverse_geocode = True
... )
>>> print(pd.DataFrame(locations))
slice_time lat long time distance_change_m address location_details
0 2024-06-07T02:00:00+00:00 32.706814 -117.156455 2024-06-07T01:50:10.92+00:00 NaN Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
1 2024-06-07T02:15:00+00:00 32.706722 -117.156576 2024-06-07T02:03:56.903+00:00 15.281598 Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
2 2024-06-07T02:30:00+00:00 32.706699 -117.156583 2024-06-07T02:22:07.571+00:00 2.588992 Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
3 2024-06-07T02:45:00+00:00 32.706699 -117.156583 2024-06-07T02:22:07.571+00:00 0.000000 Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
metric_samples(start_time, end_time, metric, fulcra_userid=None)
Retrieve the raw samples related to the given metric that occurred for the user during the specified period of time.
In cases where samples cover ranges and not points in time, a sample will be returned if any part of its range intersects with the requested range.
As an example, if you have start_date as 14:00 and end_date at 15:00,
and there is a sample that covers 13:30-14:30, it will be included.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
metric
|
str
|
The name of the metric to retrieve samples for. |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Examples:
>>> samples = fulcra.metric_samples(
... start_time="2023-08-09 07:00:00.000Z",
... end_time="2023-08-10 07:00:00.000Z",
... metric="StepCount"
... )
To inspect the first sample:
>>> samples[0]
{'start_date': '2023-08-10T06:05:10.726+00:00', 'end_date':
'2023-08-10T06:05:13.285+00:00', 'extras': None,
'has_undetermined_duration': False, 'unit': 'count', 'count': 1,
'uuid': '74983a94-8816-4b95-bbbd-d4108149261a', 'value': 8,
'source_properties': {'name': 'b c’s iPhone', 'version': '16.6',
'productType': 'iPhone12,8', 'operatingSystemVersion': [16, 6, 0],
'sourceBundleIdentifier':
'com.apple.health.F8872676-6D45-4981-8E14-C009D0AE5F27'},
'device_properties': {'name': 'iPhone', 'model':
'iPhone', 'manufacturer': 'Apple Inc.',
'hardwareVersion': 'iPhone12,8',
'softwareVersion': '16.6'}}
metric_time_series(start_time, end_time, metric, sample_rate=60, replace_nulls=False, fulcra_userid=None, calculations=None)
Retrieve time-series data from a single Fulcra metric, covering the
time starting at start_time (inclusive) until end_time
(exclusive).
If specified, the sample_rate parameter defines the number of
seconds per sample. This value can be smaller than 1. The default
value is 60 (one sample per minute).
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
metric
|
str
|
The name of the time-series metric to retrieve |
required |
sample_rate
|
float
|
The length (in seconds) of each sample |
60
|
replace_nulls
|
Optional[bool]
|
When true, replace all NA/null/None values with 0 |
False
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
calculations
|
Optional[list[str]]
|
When present, specifies additional calculations to perform for each time slice. The current values are:
- |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
a pandas DataFrame containing the data. For time ranges where data is
missing, the values will be |
Examples:
To retrieve a dataframe containing the StepCount metric:
>>> df = fulcra.metric_time_series(
... start_time = "2024-01-24 00:00:00-08:00",
... end_time = "2024-01-25 00:00:00-08:00",
... sample_rate = 1,
... metric = "StepCount"
... )
The index of the DataFrame will be the time:
df.index DatetimeIndex(['2024-01-24 08:00:00+00:00', '2024-01-24 08:00:01+00:00', '2024-01-24 08:00:02+00:00', '2024-01-24 08:00:03+00:00', '2024-01-24 08:00:04+00:00', '2024-01-24 08:00:05+00:00', '2024-01-24 08:00:06+00:00', '2024-01-24 08:00:07+00:00', '2024-01-24 08:00:08+00:00', '2024-01-24 08:00:09+00:00', ... '2024-01-25 07:59:50+00:00', '2024-01-25 07:59:51+00:00', '2024-01-25 07:59:52+00:00', '2024-01-25 07:59:53+00:00', '2024-01-25 07:59:54+00:00', '2024-01-25 07:59:55+00:00', '2024-01-25 07:59:56+00:00', '2024-01-25 07:59:57+00:00', '2024-01-25 07:59:58+00:00', '2024-01-25 07:59:59+00:00'], dtype='datetime64[us, UTC]', name='time', length=86400, freq=None)
The non-index column(s) in the dataframe will be related to the metric.
df.columns Index(['step_count'], dtype='object')
metrics_catalog()
Gets the list of time-series metrics that are available for this user.
These metrics can be passed to the `metric_time_series` function.
Returns:
The metrics, including descriptions.
Examples:
>>> metrics = fulcra_client.metrics_catalog()
>>> metrics[0]
{'name': 'AFibBurden', 'description': "A discrete measure of the percentage of time that the user's heart shows signs
of atrial fibrillation (AFib) during a given monitoring period.", 'unit': 'percent', 'is_time_series': True, 'metric_kind': 'discrete', 'value_column': 'afib_burden'} >>> metrics[1] {'name': 'ActiveCaloriesBurned', 'description': 'A cumulative measure of the amount of active energy the user has burned.', 'unit': 'cal', 'is_time_series': True, 'metric_kind': 'cumulative', 'value_column': 'active_calories_burned'}
moment_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Moment Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
numeric_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Numeric Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
record_data_type(data_type, records, api_version)
Record data for a Fulcra data type using batch ingestion.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
The Fulcra data type to record (e.g., "NumericAnnotation", "MomentAnnotation") |
required |
records
|
List[dict]
|
List of record dictionaries (schema depends on data_type) |
required |
api_version
|
str
|
API version to use (default: "v1alpha1") |
required |
Returns:
| Type | Description |
|---|---|
dict
|
Dictionary containing the upload_id |
Example
records = [ {"value": 75.5, "unit": "bpm", "note": "Resting heart rate"}, {"value": 80.2, "unit": "bpm"} ] response = client.record_data_type("NumericAnnotation", records) print(response["upload_id"])
refresh_access_token()
Refreshes the access token using the stored refresh token.
Returns:
| Type | Description |
|---|---|
bool
|
True if the token was successfully refreshed, False otherwise. |
Raises:
| Type | Description |
|---|---|
Exception
|
If no refresh token is available. |
resolve_data_type(data_type, api_version=None, fulcra_userid=None)
Resolve a data type to the matching catalog entries for a single user.
Defaults to the authenticated user ID for disambiguation if fulcra_userid is not provided. May return more than one entry when the data type exists under multiple API versions; callers are responsible for deciding whether that ambiguity is acceptable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
The data type to resolve |
required |
api_version
|
str | None
|
The API version to use (optional) |
None
|
fulcra_userid
|
str | None
|
The Fulcra user ID to use (optional) |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of matching catalog entries, all belonging to a single user. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no data types are found or they span multiple users. |
resolve_filepath(filepath, all_versions=False, fulcra_userid=None, include_deleted=False)
Take a fully qualified file path and resolve it to the resource definition
restore_annotation(annotation_id)
Restore a soft-deleted user-defined annotation by ID.
Requires a valid access token.
scale_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Scale Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
set_cached_access_token(token)
Deprecated. Directly set access token on credentials.
set_cached_access_token_expiration(expiration)
Deprecated. Directly set access token expiration on credentials.
set_cached_refresh_token(token)
Deprecated. Directly set refresh token on credentials.
set_group_participant_metadata(group_id, participant_id, metadata)
Replaces the metadata object for a participant in a group you own.
This overwrites the participant's entire metadata object; to modify
individual values, use update_group_participant_metadata instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group |
required |
participant_id
|
str
|
Participant ID within the group |
required |
metadata
|
dict
|
The new metadata object |
required |
sleep_agg(start_time, end_time, cycle_gap=None, stages=None, gap_stages=None, clip_to_range=True, mode='end', period='1d', agg_functions=None, tz='UTC', fulcra_userid=None)
Return sleep cycles aggregated by a specified period.
Processes raw sleep data samples into aggregated sleep stage durations per period.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO8601 format (exclusive). |
required |
cycle_gap
|
Optional[str]
|
Optional. Minimum time interval separating distinct cycles (e.g., "PT2H" for 2 hours). Defaults to server-side default if not provided. |
None
|
stages
|
Optional[List[int]]
|
Optional. Sleep stages to include. Defaults to all stages if not provided. |
None
|
gap_stages
|
Optional[List[int]]
|
Optional. Sleep stages to consider as gaps in sleep cycles. Defaults to server-side default if not provided. |
None
|
clip_to_range
|
Optional[bool]
|
Optional. Whether to clip the data to the requested date range. Defaults to True. This is always done when requesting data for a user other than the authenticated user. |
True
|
mode
|
Optional[str]
|
Optional. Whether to use the cycle start or cycle end to assign cycles to periods, or to split sleep stage intervals at period boundaries. Defaults to "end". |
'end'
|
period
|
Optional[str]
|
Optional. The period start and interval represented with the polars string language (see https://docs.pola.rs/api/python/dev/reference/expressions/api/polars.Expr.dt.truncate.html). Defaults to "1d". |
'1d'
|
agg_functions
|
Optional[List[str]]
|
Optional. Aggregations to return. Defaults to ["sum"] if not provided. |
None
|
tz
|
Optional[str]
|
Optional. IANA time zone to return results in. Defaults to "UTC". |
'UTC'
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A pandas DataFrame containing the aggregated sleep data. |
sleep_cycles(start_time, end_time, cycle_gap=None, stages=None, gap_stages=None, clip_to_range=True, fulcra_userid=None)
Return sleep cycles summarized from sleep stages.
Processes raw sleep data samples into sleep cycles by finding gaps in the sleep sample data within a specified time interval.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO8601 format (exclusive). |
required |
cycle_gap
|
Optional[str]
|
Optional. Minimum time interval separating distinct cycles (e.g., "PT2H" for 2 hours). Defaults to server-side default if not provided. |
None
|
stages
|
Optional[List[int]]
|
Optional. Sleep stages to include. Defaults to all stages if not provided. |
None
|
gap_stages
|
Optional[List[int]]
|
Optional. Sleep stages to consider as gaps in sleep cycles. Defaults to server-side default if not provided. |
None
|
clip_to_range
|
Optional[bool]
|
Optional. Whether to clip the data to the requested date range. Defaults to True. This is always done when requesting data for a user other than the authenticated user. |
True
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A pandas DataFrame containing the sleep cycle data. |
sleep_stages(start_time, end_time, cycle_gap=None, stages=None, gap_stages=None, merge_overlapping=True, merge_contiguous=True, clip_to_range=True, fulcra_userid=None)
Return sleep stages derived from raw fulcra metric samples.
Processes raw sleep data samples into non-conflicting sleep stages and assigns a cycle index by finding gaps in the sleep sample data within a specified time interval.
If more than one sleep data source is present, sleep stage is determined based on the priority of the stage (in bed and unknown are deprioritized) and the start time of the sample (latest takes precedence).
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO8601 format (exclusive). |
required |
cycle_gap
|
Optional[str]
|
Optional. Minimum time interval separating distinct cycles (e.g., "PT2H" for 2 hours). Defaults to server-side default if not provided. |
None
|
stages
|
Optional[List[int]]
|
Optional. Sleep stages to include. Defaults to all stages if not provided. |
None
|
gap_stages
|
Optional[List[int]]
|
Optional. Sleep stages to consider as gaps in sleep cycles. Defaults to server-side default if not provided. |
None
|
merge_overlapping
|
Optional[bool]
|
Optional. Whether to merge overlapping stages based on priority and start time. Defaults to True. |
True
|
merge_contiguous
|
Optional[bool]
|
Optional. Whether to merge contiguous samples with the same sleep stage. Defaults to True. |
True
|
clip_to_range
|
Optional[bool]
|
Optional. Whether to clip the data to the requested date range. Defaults to True. This is always done when requesting data for a user other than the authenticated user. |
True
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A pandas DataFrame containing the sleep stage data. |
tags()
Retrieves user defined tags.
Requires a valid access token.
Returns:
| Type | Description |
|---|---|
list[dict[str, str]]
|
A list of user tags; each is represented by a dict. |
update_datashare(datashare_id, datashare_name=UNSET, fulcra_data_types=UNSET, allowed_user_ids=UNSET, share_all_data=UNSET, time_start=UNSET, time_end=UNSET, allowed_group_ids=UNSET)
Updates the editable fields of a datashare that you created.
Only the fields you pass are changed; everything else is left alone.
In particular, the individual recipients (allowed_user_ids) and the
groups (allowed_group_ids) are independent lists: changing one never
disturbs the other, and passing an empty list for either removes all of
that kind of grant.
time_start and time_end accept an explicit None, which makes that
end of the share's range open. Passing None for any other parameter is
ignored by the server, since there is nothing sensible to clear it to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
datashare_id
|
str
|
UUID of the datashare to update |
required |
datashare_name
|
Optional[str]
|
New name for the datashare |
UNSET
|
fulcra_data_types
|
Optional[List[str]]
|
Replacement list of data type IDs to share |
UNSET
|
allowed_user_ids
|
Optional[List[str]]
|
Replacement list of Fulcra user IDs to share with; an empty list removes every individual recipient |
UNSET
|
share_all_data
|
Optional[bool]
|
Whether to share all data types |
UNSET
|
time_start
|
Optional[str | datetime]
|
New start of the shared range, as an ISO 8601 string
or |
UNSET
|
time_end
|
Optional[str | datetime]
|
New end of the shared range, as an ISO 8601 string or
|
UNSET
|
allowed_group_ids
|
Optional[List[str]]
|
Replacement list of group UUIDs to share with; an empty list stops sharing with every group. Every group must exist; if any does not, the server rejects the whole request and nothing about the share changes. |
UNSET
|
Returns:
| Type | Description |
|---|---|
dict
|
A dict containing the updated datashare. |
Examples:
Rename a share, touching nothing else:
>>> updated = fulcra_client.update_datashare(
... datashare_id=share_id,
... datashare_name="Updated Research Share",
... )
Add a group without disturbing the individual recipients:
>>> updated = fulcra_client.update_datashare(
... datashare_id=share_id,
... allowed_group_ids=["cf362f80-ef41-4c08-b5e3-b18bd3d1524b"],
... )
Make the share open-ended at both ends:
>>> updated = fulcra_client.update_datashare(
... datashare_id=share_id, time_start=None, time_end=None
... )
update_group(group_id, description=UNSET, header_image_url=UNSET, preview_image_url=UNSET, view_description=UNSET)
Updates the editable fields of a group that you own.
Only the fields listed here can be changed after creation; all other
group parameters are immutable. Fields that are not passed are not
modified. Passing None explicitly clears the field
(header_image_url, preview_image_url, and view_description
only; the server does not allow clearing description).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group to update |
required |
description
|
Optional[str]
|
New description for the group |
UNSET
|
header_image_url
|
Optional[str]
|
New URL of the group's header image, or None to clear it |
UNSET
|
preview_image_url
|
Optional[str]
|
New URL of the group's preview image, or None to clear it |
UNSET
|
view_description
|
Optional[dict]
|
New dict describing the group's view, or None to clear it |
UNSET
|
Returns:
| Type | Description |
|---|---|
dict
|
The updated group, represented by a dict. |
Examples:
To change a group's description (other fields are untouched):
>>> group = fulcra_client.update_group(
... group_id="cf362f80-ef41-4c08-b5e3-b18bd3d1524b",
... description="A month-long step challenge, now with prizes.",
... )
To set a header image and clear the preview image in one call:
>>> group = fulcra_client.update_group(
... group_id="cf362f80-ef41-4c08-b5e3-b18bd3d1524b",
... header_image_url="https://example.com/header.png",
... preview_image_url=None,
... )
>>> group["preview_image_url"] is None
True
update_group_participant_metadata(group_id, participant_id, values)
Updates some values on a participant's metadata in a group you own.
The given values are merged into the participant's existing metadata
object; other values are left unchanged. To replace the entire
object, use set_group_participant_metadata instead.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
group_id
|
str
|
UUID of the group |
required |
participant_id
|
str
|
Participant ID within the group |
required |
values
|
dict
|
The metadata values to set |
required |
v1_catalog_data_type(data_type, api_version, fulcra_userid=None)
Get catalog entry for a specific data type and API version, including schema.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
The Fulcra data type ID |
required |
api_version
|
str
|
API version (e.g., "v1", "v1alpha1") |
required |
fulcra_userid
|
str | None
|
Optional Fulcra user ID to filter by |
None
|
Returns:
| Type | Description |
|---|---|
Dict
|
Dictionary containing catalog entry with schema included |
Example
catalog = client.v1_catalog_data_type("NumericAnnotation", "v1alpha1") schema = catalog.get("record_spec", {}).get("schema")
v1_catalog_schema(data_type, api_version, fulcra_userid=None)
Get the JSON schema for a specific data type and API version.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
The Fulcra data type ID |
required |
api_version
|
str
|
API version (e.g., "v1", "v1alpha1") |
required |
fulcra_userid
|
str | None
|
Optional Fulcra user ID for the data type |
None
|
Returns:
| Type | Description |
|---|---|
Dict
|
Dictionary containing the JSON schema |
Raises:
| Type | Description |
|---|---|
HTTPError
|
If schema cannot be fetched (e.g., 404 if not found) |
Example
schema = client.v1_catalog_schema("NumericAnnotation", "v1alpha1") required_fields = schema.get("required", [])
validate_records(data_type, records, api_version='v1alpha1')
Validate records against the schema for a Fulcra data type.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_type
|
str
|
The Fulcra data type to validate against |
required |
records
|
List[dict]
|
List of record dictionaries to validate |
required |
api_version
|
str
|
API version to use (default: "v1alpha1") |
'v1alpha1'
|
Returns:
| Type | Description |
|---|---|
list[tuple[int, str, ValidationError]]
|
List of tuples (record_index, error_message, validation_error) for records with errors. |
list[tuple[int, str, ValidationError]]
|
Empty list if all records are valid. |
list[tuple[int, str, ValidationError]]
|
|
list[tuple[int, str, ValidationError]]
|
|
list[tuple[int, str, ValidationError]]
|
|
Raises:
| Type | Description |
|---|---|
HTTPError
|
If schema cannot be fetched |
Example
records = [ {"value": 75.5, "unit": "bpm"}, {"unit": "bpm"} # missing required 'value' ] errors = client.validate_records("NumericAnnotation", records) if errors: for idx, error_msg, error_obj in errors: print(f"Record {idx + 1}: {error_msg}")
Bases: FulcraDataAccessMixin
Accessor for the data that a group participant shares with the group owner.
Obtain an instance via FulcraAPI.group_participant. The data-access
methods (metric_time_series, metric_samples, moment_annotations,
sleep_agg, ...) have the same parameters and return types as their
FulcraAPI counterparts, but are scoped to the participant's shared
data; requests outside the group's data types or time range are
rejected by the server. The fulcra_userid parameter of these methods
cannot be used here.
Requests are authenticated by the FulcraAPI client that created this
accessor; only the group's owner can access participant data.
apple_location_updates(start_time, end_time, fulcra_userid=None)
Retrieve the raw Apple location update samples during the specified period of time.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a location update. |
Examples:
To retrieve all location updates within a specific hour:
>>> updates = fulcra.apple_location_updates(
... start_time="2023-09-24T20:00:00Z",
... end_time="2023-09-24T21:10:00Z"
... )
To see the details of the first update:
>>> updates[0]
{'speed': -1, 'horizontal_accuracy_meters': 35, 'longitude_degrees':
-117.15661336566698, 'source_is_simulated_by_software': False,
'source_is_produced_by_accessory': False, 'latitude_degrees':
32.706505158026005, 'vertical_accuracy_meters': 3.0130748748779297,
'course_heading_accuracy_degrees': -1, 'course_heading_degrees': -1,
'ellipsoidal_altitude_meters': -6.280021667480469, 'floor': 0,
'speed_accuracy_meters': -1, 'altitude_meters': 29.17388153076172, 'uuid':
'e80feacc-54e9-414f-86cb-8d6ebd85ea41', 'timestamp':
'2023-09-24T20:39:28.056+00:00'}
apple_location_visits(start_time, end_time, fulcra_userid=None)
Retrieve the raw Apple location visit samples during the specified period of time.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a location visit. |
Examples:
To retrieve all location updates within a specific hour:
>>> visits = fulcra.apple_location_visits(
... start_time="2023-09-24T20:00:00Z",
... end_time="2023-09-24T21:10:00Z"
... )
To see the details of the first update:
>>> visits[0]
{'longitude_degrees': -117.1224047932943, 'latitude_degrees':
32.75812770726706, 'arrival_date': '0001-01-01T00:00:00+00:00',
'departure_date': '2023-09-25T01:42:16.998+00:00',
'horizontal_accuracy_meters': 32.93262639589646, 'uuid':
'935971dd-0822-49ef-a74f-b09a24d68c3a'}
apple_workouts(start_time, end_time, fulcra_userid=None)
Retrieve the list of Apple workouts that occurred (at least partially) during the specified time range.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a workout. |
Examples:
To retrieve all workouts during a time period:
>>> workouts = fulcra.apple_workouts(
... start_time = "2023-09-21 07:00:00.000Z",
... end_time = "2023-09-22 07:00:00.000Z"
... )
To inspect the details of a workout:
>>> workouts[0]
{'start_date': '2023-09-21T19:18:31.733000Z', 'end_date':
'2023-09-21T19:49:08.773000Z', 'has_undetermined_duration': False,
'apple_workout_id': '480b25fe-b229-41b9-bf13-7ccf5e2092ec', 'duration':
1837.0397539138794, 'extras': {'HKTimeZone': 'America/Los_Angeles',
'HKAverageMETs': '4.37848 kcal/hr·kg' ... }
boolean_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Boolean Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
duration_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Duration Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
fulcra_api(url_path, method='GET', query=None, data=None, return_http_response=False, content_type='application/json')
Make an authenticated request to the Fulcra API, using the parent client's credentials.
fulcra_v1alpha1_api(data_class, data_type, params=None)
Make a call to the v1alpha1 API, scoped to the participant's shared data.
fulcra_v1alpha1_api_path(path, params=None)
Make a call to the v1alpha1 API using a full path, scoped to the participant's shared data.
get_metadata()
Retrieves this participant's metadata object.
Returns:
| Type | Description |
|---|---|
dict
|
The participant's metadata, represented by a dict. |
gmaps_location_updates(start_time, end_time, fulcra_source_id=None, fulcra_userid=None)
Return Google Maps geo-location update samples for a user.
Retrieve the raw Google Maps location update samples for the specified user during the specified period of time.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO 8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO 8601 format (exclusive). |
required |
fulcra_source_id
|
Optional[str]
|
Optional. When present, specifies the Fulcra source ID to filter results. |
None
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts, each of which contains the data from a Google Maps location update. |
location_at_time(time, window_size=14400, include_after=False, reverse_geocode=False, fulcra_userid=None)
Gets the user's location at the specified time. If no sample is
available for the exact time, searches for the closest sample up to
window_size seconds back. If include_after is true, then also
searches window_size seconds forward.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
time
|
Union[str, datetime]
|
The point in time to get the user's location for. |
required |
window_size
|
int
|
The size (in seconds) to look back (and optionally forward) for samples |
14400
|
include_after
|
bool
|
When true, a sample that occurs after the requested time may be returned if it is the closest one. |
False
|
reverse_geocode
|
bool
|
When true, Fulcra will attempt to reverse geocode the location and include the details in the results. |
False
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of dicts; the first dict is the best location sample. |
Examples:
location = fulcra.location_at_time( ... time = "2024-01-24 00:00:00-08:00", ... )
location [{'speed': 0, 'horizontal_accuracy_meters': 4.848857421534995, 'longitude_degrees': -117.15709954484828, 'latitude_degrees': 32.707083bb994486, 'vertical_accuracy_meters': 3.2114044806616686, 'course_heading_accuracy_degrees': 180, 'course_heading_degrees': 87.05299950647989, 'ellipsoidal_altitude_meters': 32.700060645118356, 'floor': 0, 'speed_accuracy_meters': 0.9654413396512306, 'altitude_meters': 6.15396384336054, 'uuid': '59b2d63b-9b0b-436f-a66f-01129e1b33dd', 'timestamp': '2024-01-24T00:01:45.941+00:00', 'location_source': 'apple_location_update'}]
location_time_series(start_time, end_time, change_meters=None, sample_rate=900, look_back=14400, reverse_geocode=False, fulcra_userid=None)
Retrieve a time series of locations that the user was at. This uses the most precise underlying data sources available at the given time.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
change_meters
|
Optional[float]
|
when specified, subsequent samples that are fewer than this many meters away will not be included. |
None
|
sample_rate
|
int
|
The length (in seconds) of each sample |
900
|
look_back
|
int
|
The maximum number of seconds in the past to look back to find a value for a sample. |
14400
|
reverse_geocode
|
bool
|
When true, Fulcra will attempt to reverse geocode the locations and include the details in the results. |
False
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of samples; each sample represents a location sample. |
Examples:
>>> locations = fulcra.location_time_series(
... start_time = "2024-06-06T19:00:00-07:00",
... end_time = "2024-06-06T20:00:00-07:00",
... reverse_geocode = True
... )
>>> print(pd.DataFrame(locations))
slice_time lat long time distance_change_m address location_details
0 2024-06-07T02:00:00+00:00 32.706814 -117.156455 2024-06-07T01:50:10.92+00:00 NaN Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
1 2024-06-07T02:15:00+00:00 32.706722 -117.156576 2024-06-07T02:03:56.903+00:00 15.281598 Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
2 2024-06-07T02:30:00+00:00 32.706699 -117.156583 2024-06-07T02:22:07.571+00:00 2.588992 Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
3 2024-06-07T02:45:00+00:00 32.706699 -117.156583 2024-06-07T02:22:07.571+00:00 0.000000 Petco Park, 100 Park Boulevard, San Diego, CA ... {'annotations': {'DMS': {'lat': '32° 42' 25.87...
metric_samples(start_time, end_time, metric, fulcra_userid=None)
Retrieve the raw samples related to the given metric that occurred for the user during the specified period of time.
In cases where samples cover ranges and not points in time, a sample will be returned if any part of its range intersects with the requested range.
As an example, if you have start_date as 14:00 and end_date at 15:00,
and there is a sample that covers 13:30-14:30, it will be included.
Requires an authorized access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
metric
|
str
|
The name of the metric to retrieve samples for. |
required |
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
Examples:
>>> samples = fulcra.metric_samples(
... start_time="2023-08-09 07:00:00.000Z",
... end_time="2023-08-10 07:00:00.000Z",
... metric="StepCount"
... )
To inspect the first sample:
>>> samples[0]
{'start_date': '2023-08-10T06:05:10.726+00:00', 'end_date':
'2023-08-10T06:05:13.285+00:00', 'extras': None,
'has_undetermined_duration': False, 'unit': 'count', 'count': 1,
'uuid': '74983a94-8816-4b95-bbbd-d4108149261a', 'value': 8,
'source_properties': {'name': 'b c’s iPhone', 'version': '16.6',
'productType': 'iPhone12,8', 'operatingSystemVersion': [16, 6, 0],
'sourceBundleIdentifier':
'com.apple.health.F8872676-6D45-4981-8E14-C009D0AE5F27'},
'device_properties': {'name': 'iPhone', 'model':
'iPhone', 'manufacturer': 'Apple Inc.',
'hardwareVersion': 'iPhone12,8',
'softwareVersion': '16.6'}}
metric_time_series(start_time, end_time, metric, sample_rate=60, replace_nulls=False, fulcra_userid=None, calculations=None)
Retrieve time-series data from a single Fulcra metric, covering the
time starting at start_time (inclusive) until end_time
(exclusive).
If specified, the sample_rate parameter defines the number of
seconds per sample. This value can be smaller than 1. The default
value is 60 (one sample per minute).
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
metric
|
str
|
The name of the time-series metric to retrieve |
required |
sample_rate
|
float
|
The length (in seconds) of each sample |
60
|
replace_nulls
|
Optional[bool]
|
When true, replace all NA/null/None values with 0 |
False
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for. |
None
|
calculations
|
Optional[list[str]]
|
When present, specifies additional calculations to perform for each time slice. The current values are:
- |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
a pandas DataFrame containing the data. For time ranges where data is
missing, the values will be |
Examples:
To retrieve a dataframe containing the StepCount metric:
>>> df = fulcra.metric_time_series(
... start_time = "2024-01-24 00:00:00-08:00",
... end_time = "2024-01-25 00:00:00-08:00",
... sample_rate = 1,
... metric = "StepCount"
... )
The index of the DataFrame will be the time:
df.index DatetimeIndex(['2024-01-24 08:00:00+00:00', '2024-01-24 08:00:01+00:00', '2024-01-24 08:00:02+00:00', '2024-01-24 08:00:03+00:00', '2024-01-24 08:00:04+00:00', '2024-01-24 08:00:05+00:00', '2024-01-24 08:00:06+00:00', '2024-01-24 08:00:07+00:00', '2024-01-24 08:00:08+00:00', '2024-01-24 08:00:09+00:00', ... '2024-01-25 07:59:50+00:00', '2024-01-25 07:59:51+00:00', '2024-01-25 07:59:52+00:00', '2024-01-25 07:59:53+00:00', '2024-01-25 07:59:54+00:00', '2024-01-25 07:59:55+00:00', '2024-01-25 07:59:56+00:00', '2024-01-25 07:59:57+00:00', '2024-01-25 07:59:58+00:00', '2024-01-25 07:59:59+00:00'], dtype='datetime64[us, UTC]', name='time', length=86400, freq=None)
The non-index column(s) in the dataframe will be related to the metric.
df.columns Index(['step_count'], dtype='object')
moment_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Moment Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
numeric_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Numeric Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
scale_annotations(start_time, end_time, source=None, fulcra_userid=None)
Retrieves recorded Scale Annotations, along with any metadata, for the requested time ranges.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The start of the time range (inclusive), as an ISO 8601 string or |
required |
end_time
|
Union[str, datetime]
|
The end of the range (exclusive), as an ISO 8601 string or |
required |
source
|
Optional[str]
|
When specified, the full identifier of the source to query records from |
None
|
fulcra_userid
|
Optional[str]
|
When present, specifies the Fulcra user ID to request data for |
None
|
Returns:
| Type | Description |
|---|---|
List[Dict]
|
A list of recorded annotations; each annotation is represented by a dict. |
set_metadata(metadata)
Replaces this participant's entire metadata object.
To modify individual values instead, use update_metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metadata
|
dict
|
The new metadata object |
required |
sleep_agg(start_time, end_time, cycle_gap=None, stages=None, gap_stages=None, clip_to_range=True, mode='end', period='1d', agg_functions=None, tz='UTC', fulcra_userid=None)
Return sleep cycles aggregated by a specified period.
Processes raw sleep data samples into aggregated sleep stage durations per period.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO8601 format (exclusive). |
required |
cycle_gap
|
Optional[str]
|
Optional. Minimum time interval separating distinct cycles (e.g., "PT2H" for 2 hours). Defaults to server-side default if not provided. |
None
|
stages
|
Optional[List[int]]
|
Optional. Sleep stages to include. Defaults to all stages if not provided. |
None
|
gap_stages
|
Optional[List[int]]
|
Optional. Sleep stages to consider as gaps in sleep cycles. Defaults to server-side default if not provided. |
None
|
clip_to_range
|
Optional[bool]
|
Optional. Whether to clip the data to the requested date range. Defaults to True. This is always done when requesting data for a user other than the authenticated user. |
True
|
mode
|
Optional[str]
|
Optional. Whether to use the cycle start or cycle end to assign cycles to periods, or to split sleep stage intervals at period boundaries. Defaults to "end". |
'end'
|
period
|
Optional[str]
|
Optional. The period start and interval represented with the polars string language (see https://docs.pola.rs/api/python/dev/reference/expressions/api/polars.Expr.dt.truncate.html). Defaults to "1d". |
'1d'
|
agg_functions
|
Optional[List[str]]
|
Optional. Aggregations to return. Defaults to ["sum"] if not provided. |
None
|
tz
|
Optional[str]
|
Optional. IANA time zone to return results in. Defaults to "UTC". |
'UTC'
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A pandas DataFrame containing the aggregated sleep data. |
sleep_cycles(start_time, end_time, cycle_gap=None, stages=None, gap_stages=None, clip_to_range=True, fulcra_userid=None)
Return sleep cycles summarized from sleep stages.
Processes raw sleep data samples into sleep cycles by finding gaps in the sleep sample data within a specified time interval.
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO8601 format (exclusive). |
required |
cycle_gap
|
Optional[str]
|
Optional. Minimum time interval separating distinct cycles (e.g., "PT2H" for 2 hours). Defaults to server-side default if not provided. |
None
|
stages
|
Optional[List[int]]
|
Optional. Sleep stages to include. Defaults to all stages if not provided. |
None
|
gap_stages
|
Optional[List[int]]
|
Optional. Sleep stages to consider as gaps in sleep cycles. Defaults to server-side default if not provided. |
None
|
clip_to_range
|
Optional[bool]
|
Optional. Whether to clip the data to the requested date range. Defaults to True. This is always done when requesting data for a user other than the authenticated user. |
True
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A pandas DataFrame containing the sleep cycle data. |
sleep_stages(start_time, end_time, cycle_gap=None, stages=None, gap_stages=None, merge_overlapping=True, merge_contiguous=True, clip_to_range=True, fulcra_userid=None)
Return sleep stages derived from raw fulcra metric samples.
Processes raw sleep data samples into non-conflicting sleep stages and assigns a cycle index by finding gaps in the sleep sample data within a specified time interval.
If more than one sleep data source is present, sleep stage is determined based on the priority of the stage (in bed and unknown are deprioritized) and the start time of the sample (latest takes precedence).
Requires a valid access token.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start_time
|
Union[str, datetime]
|
The starting timestamp in ISO8601 format (inclusive). |
required |
end_time
|
Union[str, datetime]
|
The ending timestamp in ISO8601 format (exclusive). |
required |
cycle_gap
|
Optional[str]
|
Optional. Minimum time interval separating distinct cycles (e.g., "PT2H" for 2 hours). Defaults to server-side default if not provided. |
None
|
stages
|
Optional[List[int]]
|
Optional. Sleep stages to include. Defaults to all stages if not provided. |
None
|
gap_stages
|
Optional[List[int]]
|
Optional. Sleep stages to consider as gaps in sleep cycles. Defaults to server-side default if not provided. |
None
|
merge_overlapping
|
Optional[bool]
|
Optional. Whether to merge overlapping stages based on priority and start time. Defaults to True. |
True
|
merge_contiguous
|
Optional[bool]
|
Optional. Whether to merge contiguous samples with the same sleep stage. Defaults to True. |
True
|
clip_to_range
|
Optional[bool]
|
Optional. Whether to clip the data to the requested date range. Defaults to True. This is always done when requesting data for a user other than the authenticated user. |
True
|
fulcra_userid
|
Optional[str]
|
Optional. When present, specifies the Fulcra user ID to request data for. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
A pandas DataFrame containing the sleep stage data. |
update_metadata(values)
Updates some values on this participant's metadata.
The given values are merged into the existing metadata object; other
values are left unchanged. To replace the entire object, use
set_metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
values
|
dict
|
The metadata values to set |
required |