Skip to main content

Creating Members

Connect a person in your system to a Member in a Gravity Rail Workspace. Create one synthetic Member first, then use CSV import for a batch.

A person's Account is global. Organizations contain Workspaces; membership and roles are assigned at each level.

An Account is global; Organization and Workspace memberships each have their own role.

The same Account can have different memberships and roles in different Organizations and Workspaces. This diagram shows a person's memberships; Agents are also Members, but do not require a person's Account.

For the product's import wizard and role settings, use Importing Members and Member roles. This guide covers API requests and identity reconciliation.

Before you begin​

For /create-signup, use an account or organization API key with org:admin authorized for the target Workspace. Choose the key using Authentication. Store it in an environment variable or secrets manager.

Use synthetic data while developing. Before sending patient information, meet the PHI requirements, including a signed BAA and confirmed workspace configuration.

Create a Member​

Set GRAVITYRAIL_API_KEY and GRAVITYRAIL_WORKSPACE_UUID, then send:

curl --fail-with-body --request POST \
"https://api.gravityrail.com/api/v2/w/${GRAVITYRAIL_WORKSPACE_UUID}/create-signup" \
--header "Authorization: Bearer ${GRAVITYRAIL_API_KEY}" \
--header "Content-Type: application/json" \
--data '{
"member": {
"email": "integration-test@example.com",
"name": "Integration Test",
"externalId": "integration-test-001"
}
}'

Provide at least one of email, phone, or externalId. Use externalId for your system's stable identifier. To select a role explicitly, supply member.role with an existing non-admin role name; signup cannot assign an admin role.

Check member.id and wasCreated in the response. wasCreated distinguishes a new Member from a match to an existing one. Keep the Member ID for subsequent requests and treat any returned token as a credential. Open Members in the Workspace to verify the result.

Do not log the response body, contact values, Form values, or returned tokens. Use IDs when reporting an error and follow Error handling.

Preview a CSV import​

A Member import requires members:admin and a valid role ID for newly created Members. Obtain the role ID from the Member Roles API. The signup request's organization scope and the import request's Member scope are separate contracts.

Save a synthetic members.csv:

email,name,external_id
integration-test@example.com,Integration Test,integration-test-001
second-test@example.com,Second Test,integration-test-002

Set GRAVITYRAIL_NEW_MEMBER_ROLE_ID to the selected role ID. Preview the file before writing:

curl --fail-with-body --request POST \
"https://api.gravityrail.com/api/v2/w/${GRAVITYRAIL_WORKSPACE_UUID}/members/import/preview?new_member_role_id=${GRAVITYRAIL_NEW_MEMBER_ROLE_ID}" \
--header "Authorization: Bearer ${GRAVITYRAIL_API_KEY}" \
--form "file=@members.csv"

Review the create, update, unchanged, conflict, skipped, and error counts. Resolve identity conflicts before importing. A row whose contact values disagree with the matched Account needs an explicit resolution; do not select overwrite as a substitute for reviewing the match.

Start and verify the import​

Submit the reviewed file as a durable import:

curl --fail-with-body --no-buffer --request POST \
"https://api.gravityrail.com/api/v2/w/${GRAVITYRAIL_WORKSPACE_UUID}/members/import/runs?new_member_role_id=${GRAVITYRAIL_NEW_MEMBER_ROLE_ID}" \
--header "Authorization: Bearer ${GRAVITYRAIL_API_KEY}" \
--form "file=@members.csv"

The response is an SSE stream with import_run, import_item, and done events. Keep the run ID. If the connection closes, find its summary with GET /members/import/runs, and retrieve row outcomes with GET /members/import/runs/{run_id}/items; a disconnected stream does not cancel the import. See the Members API for event and resolution formats.

Check the final created, updated, skipped, and failed outcomes. Correct rejected rows and preview them again before resubmitting.

Matching an exported Member​

When re-importing a Gravity Rail Member export, preserve its id or uuid and contact/external_id columns. A numeric ID is local to its Workspace: use an export from the same Workspace. Its row must corroborate that ID with an existing contact or external identifier, without conflicting values. An unrecognized or conflicting explicit key fails the row rather than updating a different Member. A matching Workspace Member UUID does not require the same corroboration.

CSV email matching is case-insensitive. Ambiguous matches fail rather than selecting an arbitrary Member. Use the preview and row outcomes to resolve them.

Update through your external identifier​

Once your Member exists, a synchronization job can address it without persisting its numeric ID:

curl --fail-with-body --request PUT \
"https://api.gravityrail.com/api/v2/w/${GRAVITYRAIL_WORKSPACE_UUID}/members/by-external-id/integration-test-001" \
--header "Authorization: Bearer ${GRAVITYRAIL_API_KEY}" \
--header "Content-Type: application/json" \
--data '{"description": "Synthetic integration test"}'

The external ID must identify a Member in the target Workspace; an unknown ID returns 404. Use the Members API for update permissions, labels, notification preferences, archive operations, and complete schemas. Use Importing Data to synchronize that Member's Form records.