Skip to main content

Importing Members into Gravity Rail

Members are the users in your Gravity Rail workspace. This guide shows you how to create members, assign roles, and manage their data.

Understanding Accounts, Workspaces, and Members

Gravity Rail has a three-part user model:

graph TB
A["Account<br/>(Global User)<br/>email, phone, name"]
W["Workspace<br/>(Team/Project)<br/>slug, settings"]
M["Member<br/>(User in Workspace)<br/>member_role_id<br/>account_uuid"]
L["Member Role<br/>(Permissions)<br/>granted_scopes"]

A -->|workspace_membership| W
M -->|references| A
M -->|workspace_id| W
M -->|member_role_id| L

style A fill:#e1f5ff
style W fill:#f3e5f5
style M fill:#e8f5e9
style L fill:#fff3e0

Key relationships:

  • Account: A global user record (email, phone, name) shared across your organization
  • Workspace: A team, project, or customer workspace with its own members and data
  • Member: An account's participation in a specific workspace with a role
  • Member Role: Defines permissions (manage workspace, access data types, etc.)

A single account can be a member of multiple workspaces with different roles.

Creating Members

Via API (Signup Endpoint)

The /create-signup endpoint creates or updates members and their associated data in a single operation:

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/create-signup \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"member": {
"email": "alice@example.com",
"phone": "+1-555-123-4567",
"name": "Alice Johnson",
"dateOfBirth": "1980-06-15",
"externalId": "user_123",
"role": "Support Agent",
"locale": "en-US",
"tosAccepted": true,
"labels": ["vip", "premium"]
},
"data": {
"patient": {
"externalId": "pat_456",
"values": {
"first_name": "Alice",
"email": "alice@example.com",
"medical_id": "MED123456"
}
}
}
}'

Request fields:

  • member.email - (optional if phone or externalId provided) Email address
  • member.phone - (optional if email or externalId provided) Phone number (will be normalized)
  • member.name - (optional) Display name
  • member.dateOfBirth - (optional) Date of birth in YYYY-MM-DD format
  • member.externalId - (optional) Your system's user ID for easy lookups
  • member.role - (optional) Name of the member role. Must be non-admin. Defaults to first non-admin role if omitted
  • member.locale - (optional) Locale code (e.g., "en-US", "fr-FR")
  • member.tosAccepted - (optional) Whether the user accepted terms of service
  • member.labels - (optional) Array of label slugs to assign to the member
  • data - (optional) Object with data type slugs mapping to records to create/update

Response:

{
"token": "eyJhbGc...",
"account": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"email": "alice@example.com",
"phone": "+1-555-123-4567",
"name": "Alice Johnson"
},
"member": {
"id": 42,
"email": "alice@example.com",
"memberRoleId": 5,
"labels": [
{ "id": 1, "slug": "vip", "name": "VIP" },
{ "id": 2, "slug": "premium", "name": "Premium" }
]
},
"wasCreated": true
}

Requirements:

  • Your API key must have the account:create scope
  • Either email, phone, or externalId must be provided
  • Email format is validated and normalized to lowercase
  • Phone format is validated and normalized
  • Role names must not have admin privileges (roles with admin-level scopes)

Via Import UI

The Members import interface provides a visual way to bulk create/update members:

  1. Navigate to your workspace members page
  2. Click the Import button
  3. Select a CSV file with member data
  4. Choose a role for newly created members
  5. Review the import preview
  6. Confirm to import

CSV Format:

email,phone,name,date_of_birth,external_id,description,labels,notify_email,notify_sms,notify_voice,form.patient.first_name,form.patient.medical_id
alice@example.com,+1-555-123-4567,Alice Johnson,1980-06-15,user_123,Support specialist,"vip,premium",1,1,0,Alice,MED123456
bob@example.com,+1-555-123-4568,Bob Smith,1991-11-03,user_124,Junior support,standard,1,0,1,Bob,MED123457

CSV Requirements:

  • CSV format with headers in the first row
  • At least one of: email, phone, or external_id per row
  • date_of_birth accepts YYYY-MM-DD
  • Boolean columns (notify_*) accept true/false or 1/0
  • Labels are comma-separated; quote the CSV cell when it contains commas
  • Form data uses dot notation: form.{data_type_slug}.{field_slug}
  • Maximum 10,000 rows per import
  • Maximum file size: 10 MB

Via Direct API

Create individual members with the /members endpoint:

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"phone": "+1-555-123-4567",
"name": "Alice Johnson",
"dateOfBirth": "1980-06-15",
"description": "Support specialist",
"externalId": "user_123",
"memberRoleId": 5,
"labelIds": [1, 2],
"locale": "en-US",
"notifyEmail": true,
"notifySms": true,
"notifyVoice": false
}'

Updating Members

Via API

Update an existing member:

curl -X PUT https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members/{member_id} \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Alice Johnson",
"email": "alice.johnson@example.com",
"phone": "+1-555-123-4599",
"dateOfBirth": "1980-06-15",
"description": "Senior support specialist",
"memberRoleId": 6,
"labelIds": [1, 3],
"notifyEmail": true
}'

Via CSV Import

Re-importing the same members (matched by email or phone) will update their fields:

# This will update Alice if she already exists
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members/import \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@members.csv" \
-F "newMemberRoleId=5"

The import returns progress updates as streaming NDJSON:

{"type":"progress","current":1,"total":100,"success":1,"failed":0,"created":1,"updated":0,"unchanged":0}
{"type":"progress","current":2,"total":100,"success":2,"failed":0,"created":1,"updated":1,"unchanged":0}
{"type":"complete","success":98,"failed":2,"total":100,"created":50,"updated":48,"unchanged":0,"errors":["Row 15: Invalid email..."],"failedRows":[15,27],"updatedMembers":[...]}

Member Roles and Permissions

Member roles control what a member can do in your workspace:

View Available Roles

curl https://api.gravityrail.com/api/v2/w/{workspace_uuid}/member-roles \
-H "Authorization: Bearer YOUR_API_KEY"

Response:

[
{
"id": 1,
"name": "Admin",
"useAdmin": true,
"manageWorkspace": true,
"permissions": ["workspace:admin", "members:manage", "data:manage"]
},
{
"id": 5,
"name": "Support Agent",
"useAdmin": false,
"manageWorkspace": false,
"permissions": ["chats:read", "chats:write", "data:read:patient"]
}
]

Create Custom Roles

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/member-roles \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Support Agent",
"permissions": [
"chats:read",
"chats:write",
"data:read:patient",
"data:write:patient"
]
}'

Managing Member Data

When you create or update a member, you can simultaneously create/update their associated data records:

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/create-signup \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"member": {
"email": "alice@example.com",
"name": "Alice Johnson",
"role": "Support Agent"
},
"data": {
"employee": {
"externalId": "emp_123",
"values": {
"department": "Support",
"start_date": "2024-01-15",
"manager": "Bob Smith"
}
},
"patient": {
"externalId": "pat_789",
"values": {
"first_name": "Alice",
"medical_id": "MED123456"
}
}
}
}'

Each data record is matched by external ID:

  • If a record with that external ID exists: It's updated with new values
  • If no record exists: A new record is created
  • For non-collection data types: If no external ID match exists but the member has an existing record, that record is updated with the new external ID

See Understanding Data for more on data types and records.

Member Labels

Labels organize members into groups for reporting and filtering:

# Create a label
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/member-labels \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "VIP",
"slug": "vip",
"color": "#FF6B6B"
}'

# Assign labels when creating members
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"labelIds": [1, 2, 3]
}'

Member Notifications

Control how members are notified of updates:

curl -X PUT https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members/{member_id} \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"notifyEmail": true, # Email notifications enabled
"notifySms": true, # SMS notifications enabled
"notifyVoice": false # Voice notifications disabled
}'

Best Practices

  1. Use External IDs: Always provide an externalId matching your system's user ID for easy reconciliation and lookups
  2. Validate Phone Numbers: Ensure phone numbers are in E.164 format (e.g., +1-555-123-4567)
  3. Batch Operations: Use CSV import for large numbers of members rather than individual API calls
  4. Handle Duplicates: The system prevents duplicate emails and phones - use the import response to handle conflicts
  5. Preserve Role Hierarchy: Only admins can assign admin roles; non-admin role assignment via signup API is enforced

Common Workflows

Sync Users from Your CRM

# Export users from your CRM as CSV
csv_data=$(curl https://your-crm.com/api/users/export)

# Import to Gravity Rail
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members/import \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@-" \
-F "newMemberRoleId=5" \
<<< "$csv_data"

Create Member + Patient Record

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/create-signup \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"member": {
"email": "patient@example.com",
"name": "John Doe",
"role": "Patient"
},
"data": {
"patient": {
"externalId": "patient_789",
"values": {
"date_of_birth": "1990-01-15",
"medical_id": "MED789012",
"insurance": "Blue Cross"
}
}
}
}'

Update Multiple Members

# Export current members
curl https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members/export \
-H "Authorization: Bearer YOUR_API_KEY" \
> members.csv

# Edit members.csv locally (update roles, labels, etc.)

# Re-import
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/members/import \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@members.csv" \
-F "newMemberRoleId=5"

API Reference

For complete API documentation, see API Reference.

Key endpoints:

  • POST /w/{workspace_uuid}/create-signup - Create or update member with role and data
  • GET /w/{workspace_uuid}/members - List members with filtering
  • POST /w/{workspace_uuid}/members - Create individual member
  • PUT /w/{workspace_uuid}/members/{member_id} - Update member
  • DELETE /w/{workspace_uuid}/members/{member_id} - Delete member
  • POST /w/{workspace_uuid}/members/import - Import members from CSV
  • POST /w/{workspace_uuid}/members/export - Export members to CSV
  • GET /w/{workspace_uuid}/member-roles - List available roles
  • POST /w/{workspace_uuid}/member-roles - Create custom role