Skip to main content

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:

  1. REST API: Programmatic data creation via HTTP endpoints
  2. CSV Import: Bulk upload via UI or API
  3. Webhook Integration: Automatically import when external events occur
  4. 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

  1. Navigate to your workspace
  2. Click the Data menu (or your workspace name)
  3. Select the Data Types or Forms section
  4. Choose a data type to view its records/entries

Creating Records in the UI

  1. In the Forms interface, click + New Entry
  2. Fill out the form with your data
  3. 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:

  1. In the Forms/Entries tab, click Import
  2. Prepare a CSV file with:
    • Headers matching the data type's field slugs
    • One record per row
  3. Select the CSV file
  4. Review the import preview
  5. 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

  1. Navigate to your workspace's Files section
  2. Click + Upload File or drag-and-drop
  3. Select a file from your computer
  4. Choose a folder (optional)
  5. Add a name and description
  6. 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

  1. Go to Data > Forms > Customer
  2. Click Import
  3. Upload customers.csv
  4. Review the preview
  5. 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

  1. Validate before import: Ensure all required fields are present
  2. Type checking: Dates must be valid dates, emails must be valid format
  3. Duplicate checking: Use external IDs to prevent duplicate records
  4. Batch operations: Bulk operations are more efficient than individual creates

External IDs

  1. Always use external IDs: Match your source system's IDs (Stripe ID, EMR ID, etc.)
  2. Make them searchable: Mark external ID fields as shouldIndex: true
  3. Keep them consistent: Don't change external IDs between syncs
  4. Handle collisions: If an external ID exists, update the record instead of creating a new one

Performance

  1. Batch imports: For large datasets, use bulk endpoints rather than individual record creation
  2. Index strategically: Index fields you'll frequently search/filter by
  3. Limit pagination: For large result sets, use smaller page sizes and iterate
  4. Monitor rate limits: The API has rate limits; implement exponential backoff for retries

Data Organization

  1. Use folders for files: Organize documents hierarchically so they're easy to find
  2. Meaningful names: Use clear, descriptive names for records and files
  3. 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 record
  • PUT /w/{workspace_uuid}/data-types/{data_type_id}/records/{record_id} - Update record
  • POST /w/{workspace_uuid}/folders - Create folder
  • POST /w/{workspace_uuid}/files - Upload file
  • GET /w/{workspace_uuid}/folders/{folder_id}/files - List folder contents