Importing Data into Gravity Rail
This guide shows you how to populate Gravity Rail with data records, using both REST APIs and the web UI.
Overview
Data flows into Gravity Rail through multiple paths:
- REST API: Programmatic data creation via HTTP endpoints
- CSV Import: Bulk upload via UI or API
- Webhook Integration: Automatically import when external events occur
- Member Signup: Create members + their data in a single operation
This guide covers direct API and UI methods. See Importing Members for member-focused workflows.
Creating Data Records via API
Single Record Creation
Create a data record for the authenticated member:
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/{data_type_id}/records \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fieldValues": {
"first_name": "Alice",
"email": "alice@example.com",
"status": "active"
},
"externalId": "cust_123"
}'
Response:
{
"id": 789,
"dataTypeId": 123,
"memberId": 42,
"externalId": "cust_123",
"fieldValues": {
"first_name": "Alice",
"email": "alice@example.com",
"status": "active"
},
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-01-15T10:00:00Z"
}
Creating Multiple Records
To create multiple records efficiently, make individual API calls for each record, or use CSV import for bulk operations.
Update Existing Records
Update a record by ID:
curl -X PUT https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/{data_type_id}/records/{record_id} \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fieldValues": {
"status": "inactive",
"last_updated": "2024-01-20"
}
}'
Or update by external ID:
curl -X PUT "https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/{data_type_id}/records?externalId=cust_123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fieldValues": {
"status": "inactive"
}
}'
Bulk Import via UI
The Gravity Rail UI provides a visual forms interface for entering and importing data.
Accessing the Forms Interface
- Navigate to your workspace
- Click the Data menu (or your workspace name)
- Select the Data Types or Forms section
- Choose a data type to view its records/entries
Creating Records in the UI
- In the Forms interface, click + New Entry
- Fill out the form with your data
- Click Save
The form automatically validates field types (dates must be valid dates, emails must be valid, etc.).
Importing Multiple Records from CSV
To bulk-import data records:
- In the Forms/Entries tab, click Import
- Prepare a CSV file with:
- Headers matching the data type's field slugs
- One record per row
- Select the CSV file
- Review the import preview
- Click Confirm Import
CSV Format Example:
For a patient data type with fields first_name, last_name, emr_id, admission_date:
first_name,last_name,emr_id,admission_date
Alice,Johnson,EMR-001,2024-01-15
Bob,Smith,EMR-002,2024-01-16
Carol,Williams,EMR-003,2024-01-17
CSV Format with External ID:
first_name,last_name,emr_id,admission_date,__externalId
Alice,Johnson,EMR-001,2024-01-15,pat_001
Bob,Smith,EMR-002,2024-01-16,pat_002
Carol,Williams,EMR-003,2024-01-17,pat_003
Limitations
- CSV import creates records without specifying ownership (defaults to current member)
- For fine-grained control over record ownership, use the API directly
- Maximum file size: 10 MB
- Maximum rows: 10,000 per import
Importing with External IDs
External IDs help you match records to external systems and prevent duplicates:
Using External IDs to Update Records
If a record with the same external ID already exists, it's updated instead of creating a duplicate:
# First import
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/123/records \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fieldValues": {
"first_name": "Alice",
"email": "alice@example.com"
},
"externalId": "EMR-001"
}'
# Later, updating with the same external ID updates the record
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/123/records \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fieldValues": {
"first_name": "Alice",
"email": "alice.johnson@example.com"
},
"externalId": "EMR-001"
}'
The result: One record is created/updated, not two.
Syncing Data from External Systems
External IDs are critical for keeping Gravity Rail in sync with your source systems:
# Example: Sync customers from Stripe to Gravity Rail
import requests
import stripe
# 1. Get customers from Stripe
stripe_customers = stripe.Customer.list(limit=100)
# 2. Sync each to Gravity Rail
api_key = "your_api_key"
workspace_uuid = "your_workspace_uuid"
for customer in stripe_customers:
response = requests.post(
f"https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/123/records",
headers={"Authorization": f"Bearer {api_key}"},
json={
"fieldValues": {
"name": customer.name,
"email": customer.email,
"phone": customer.phone or "",
"stripe_customer_id": customer.id,
},
"externalId": customer.id # Use Stripe customer ID as external ID
}
)
print(f"Synced {customer.email}: {response.status_code}")
File Upload and Organization
Files store reference documents and provide context to AI agents.
Create a Folder
Organize files hierarchically:
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/folders \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Product Documentation",
"slug": "product-docs",
"description": "Reference guides for product support",
"parentFolderId": null
}'
Upload a File
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/files \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@product-guide.pdf" \
-F "name=Product Guide" \
-F "description=Complete user guide" \
-F "folderId=1"
Supported file types:
- Documents: PDF, Word, Text, Markdown
- Images: PNG, JPG, GIF, SVG
- Data: CSV, JSON, XML
- Media: MP3, MP4 (with size limits)
Upload Files via UI
- Navigate to your workspace's Files section
- Click + Upload File or drag-and-drop
- Select a file from your computer
- Choose a folder (optional)
- Add a name and description
- Click Upload
Organize with Folders
Create a folder structure that makes sense for your organization:
├── Product Documentation
│ ├── User Guides
│ │ ├── Getting Started.pdf
│ │ └── Advanced Features.pdf
│ └── API Reference
│ └── API Docs.pdf
├── Support Guidelines
│ ├── Escalation Procedures.pdf
│ └── FAQ.md
└── Legal
├── Terms of Service.pdf
└── Privacy Policy.pdf
Retrieving Files
List files in a folder:
curl "https://api.gravityrail.com/api/v2/w/{workspace_uuid}/folders/{folder_id}/files" \
-H "Authorization: Bearer YOUR_API_KEY"
Download a file:
curl "https://api.gravityrail.com/api/v2/w/{workspace_uuid}/files/{file_id}/download" \
-H "Authorization: Bearer YOUR_API_KEY" \
-o downloaded_file.pdf
Complete Import Workflow
Here's a step-by-step example: importing customer data from a CSV file:
Step 1: Prepare Your Data
customers.csv:
first_name,last_name,email,phone,company,stripe_id,account_status
Alice,Johnson,alice@example.com,+1-555-001-0001,Acme Inc,cus_001,active
Bob,Smith,bob@example.com,+1-555-001-0002,TechCorp,cus_002,active
Carol,Williams,carol@example.com,+1-555-001-0003,Global Ltd,cus_003,inactive
Step 2: Create the Data Type
curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer",
"slug": "customer",
"isCollection": false,
"fields": [
{
"name": "First Name",
"slug": "first_name",
"fieldType": "text",
"required": true,
"shouldIndex": true
},
{
"name": "Last Name",
"slug": "last_name",
"fieldType": "text",
"required": true,
"shouldIndex": true
},
{
"name": "Email",
"slug": "email",
"fieldType": "email",
"required": true,
"shouldIndex": true
},
{
"name": "Phone",
"slug": "phone",
"fieldType": "phone",
"required": false,
"shouldIndex": true
},
{
"name": "Company",
"slug": "company",
"fieldType": "text",
"required": false,
"shouldIndex": true
},
{
"name": "Stripe ID",
"slug": "stripe_id",
"fieldType": "text",
"required": false,
"shouldIndex": true
},
{
"name": "Account Status",
"slug": "account_status",
"fieldType": "select",
"required": true,
"shouldIndex": true
}
]
}'
Step 3: Import via UI
- Go to Data > Forms > Customer
- Click Import
- Upload
customers.csv - Review the preview
- Confirm
Or create records individually via API. For large volumes, CSV import via the UI is more efficient.
Step 4: Verify
Query the imported records:
curl "https://api.gravityrail.com/api/v2/w/{workspace_uuid}/data-types/123/records" \
-H "Authorization: Bearer YOUR_API_KEY"
Best Practices
Data Validation
- Validate before import: Ensure all required fields are present
- Type checking: Dates must be valid dates, emails must be valid format
- Duplicate checking: Use external IDs to prevent duplicate records
- Batch operations: Bulk operations are more efficient than individual creates
External IDs
- Always use external IDs: Match your source system's IDs (Stripe ID, EMR ID, etc.)
- Make them searchable: Mark external ID fields as
shouldIndex: true - Keep them consistent: Don't change external IDs between syncs
- Handle collisions: If an external ID exists, update the record instead of creating a new one
Performance
- Batch imports: For large datasets, use bulk endpoints rather than individual record creation
- Index strategically: Index fields you'll frequently search/filter by
- Limit pagination: For large result sets, use smaller page sizes and iterate
- Monitor rate limits: The API has rate limits; implement exponential backoff for retries
Data Organization
- Use folders for files: Organize documents hierarchically so they're easy to find
- Meaningful names: Use clear, descriptive names for records and files
- Metadata: Add descriptions to data types and files to document their purpose
Common Workflows
Sync CRM Data
# Export contacts from HubSpot API
contacts=$(curl https://api.hubapi.com/crm/v3/objects/contacts \
-H "Authorization: Bearer ${HUBSPOT_TOKEN}")
# Import each contact to Gravity Rail
echo "$contacts" | jq -r '.results[] | @json' | while read contact; do
curl -X POST https://api.gravityrail.com/api/v2/w/${WORKSPACE_UUID}/data-types/123/records \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d "$(echo $contact | jq '{
fieldValues: {
first_name: .properties.firstname.value,
last_name: .properties.lastname.value,
email: .properties.email.value,
company: .properties.company.value
},
externalId: .id
}')"
done
Import E-Commerce Product Data
# Download product catalog
curl https://your-store.com/api/products?limit=1000 > products.json
# Transform to CSV and import
jq -r '.products[] | [.id, .name, .sku, .price, .inventory_count, .category] | @csv' \
products.json > products.csv
# Upload via UI or API
curl -X POST https://api.gravityrail.com/api/v2/w/${WORKSPACE_UUID}/data-types/123/records/bulk \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d @payload.json
Import Time-Series Data
For collection types (multiple records per member):
# Import transaction history for a customer
curl -X POST https://api.gravityrail.com/api/v2/w/${WORKSPACE_UUID}/data-types/123/records/bulk \
-H "Authorization: Bearer ${API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"records": [
{
"fieldValues": {
"date": "2024-01-15T10:30:00Z",
"amount": 99.99,
"description": "Product purchase",
"status": "completed"
},
"externalId": "txn_001"
},
{
"fieldValues": {
"date": "2024-01-20T14:15:00Z",
"amount": 49.99,
"description": "Refund",
"status": "completed"
},
"externalId": "txn_002"
}
]
}'
API Reference
For complete API documentation, see API Reference.
Key endpoints:
POST /w/{workspace_uuid}/data-types/{data_type_id}/records- Create single recordPUT /w/{workspace_uuid}/data-types/{data_type_id}/records/{record_id}- Update recordPOST /w/{workspace_uuid}/folders- Create folderPOST /w/{workspace_uuid}/files- Upload fileGET /w/{workspace_uuid}/folders/{folder_id}/files- List folder contents