Skip to main content

Getting Started with Integration

This guide walks you through the essential steps to integrate Gravity Rail into your application, from creating your first member to receiving webhooks for data updates.

Overview

The typical integration flow follows these steps:

  1. Authentication - Generate an API key
  2. Register Members - Create users in your workspace
  3. Add Member Metadata - Attach custom data to members
  4. Initiate Conversations - Start SMS or chat communications
  5. Deliver Messages - Handle SMS opt-in and message delivery
  6. Export Data - Set up webhooks to receive updates
  7. Connect with MCP - Integrate AI tools and workflows

Let's walk through each step.

Step 1: Authentication

If you haven't already, generate an API key:

  1. Log in to your Gravity Rail account
  2. Open Settings (top-right) and select API Keys under the Developer section
  3. Click Create API Key, name the key, choose scopes and expiration, then create it
  4. Copy and securely store your API key — the full secret is shown once

All API requests require this key in the Authorization header:

curl https://api.gravityrail.com/api/v2/w \
-H "Authorization: Bearer YOUR_API_KEY"

For complete authentication details, see the Authentication Guide.

Step 2: Register a Member

Members are the users in your Gravity Rail workspace. Create your first member using the signup endpoint:

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": "customer@example.com",
"phone": "+1-555-123-4567",
"name": "Jane Customer",
"externalId": "customer_001"
}
}'

Response:

{
"token": "eyJhbGc...",
"account": {
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"email": "customer@example.com",
"phone": "+1-555-123-4567",
"name": "Jane Customer"
},
"member": {
"id": 42,
"email": "customer@example.com",
"memberRoleId": 5
},
"wasCreated": true
}

Key Points:

  • Either email or phone is required
  • externalId links to your system's user ID for easy lookups
  • The response includes a token for member authentication (optional)
  • wasCreated: true means this is a new member, false means they already existed

Step 3: Include Member Metadata

Attach custom data to members by defining data types and creating records. This allows you to store patient information, customer profiles, or any structured data.

Define a Data Type

First, create a data type schema (this is typically done once via the UI or API):

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": "Patient",
"slug": "patient",
"isCollection": false,
"fields": [
{
"slug": "medical_id",
"name": "Medical ID",
"fieldType": "text",
"required": true
},
{
"slug": "date_of_birth",
"name": "Date of Birth",
"fieldType": "date",
"required": true
},
{
"slug": "insurance_provider",
"name": "Insurance Provider",
"fieldType": "text"
}
]
}'

Add Data During Member Creation

Include data records when creating members:

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",
"phone": "+1-555-123-4567",
"name": "Jane Patient",
"externalId": "patient_001"
},
"data": {
"patient": {
"externalId": "medical_record_001",
"values": {
"medical_id": "MED123456",
"date_of_birth": "1985-06-15",
"insurance_provider": "Blue Cross"
}
}
}
}'

The data object maps data type slugs to records. Each record can have:

  • externalId - Your system's identifier for this record
  • values - Key-value pairs matching the data type fields

For more details, see Understanding Data in Gravity Rail.

Step 4: Initiate a Chat

Start a conversation with a member via SMS, voice, or web chat.

A workflow-driven chat is created by passing a workflowId. The assignment that runs the workflow is created automatically; do not create an assignment first.

Create an SMS Chat

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/chats \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "phone-sms",
"workflowId": 42,
"memberId": 123,
"phoneNumberId": 123,
"title": "Patient Check-in"
}'

Parameters:

  • channel - Communication channel: phone-sms, phone-voice, web-chat, or email
  • workflowId - Workflow the agent runs the conversation through. Omit for a simple chat with no workflow.
  • memberId - Member this chat is for. Defaults to the authenticated member.
  • phoneNumberId - Your Gravity Rail phone number ID (required for SMS/voice unless the workflow has a default)
  • assistantEnabled - Defaults to true; set false for an operator-driven chat with no AI response
  • participants - Optional extra member participants, such as an assistant or operator member
  • title - Optional chat title for organization

Response:

{
"id": 789,
"uuid": "chat-uuid-here",
"channel": "phone-sms",
"workflowId": 42,
"participants": [
{
"memberId": 123,
"role": "user",
"name": "Jane Patient"
}
],
"createdAt": "2024-01-15T10:00:00Z"
}

Place a Voice Call That Runs a Workflow

For phone-voice, creating an assistant-enabled workflow chat also places the outbound call. The member is dialed and the agent runs the workflow in that call.

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/chats \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel": "phone-voice",
"workflowId": 42,
"memberId": 123,
"phoneNumberId": 7,
"assistantEnabled": true
}'
  • Omit phoneNumberId only when the workflow has a configured default phone number.
  • The returned chat's id is what you use later to fetch messages (GET /chats/{chat_id}/messages) or the recording (GET /recordings/chat/{chat_id}/audio.wav).

Send a Message

Send a message in the chat:

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/chats/{chat_id}/send-assistant-message \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "Hi Jane, this is a reminder about your appointment tomorrow at 2pm. Reply YES to confirm."
}'

The agent will send this message to all chat participants via the configured channel (SMS, voice, etc.).

Step 5: Delivering Messages (SMS Opt-in)

To send SMS messages to members, they must opt in to receive messages. Here's how to handle SMS delivery:

Understanding SMS Opt-in Requirements

TCPA Compliance: US regulations require explicit consent before sending SMS messages.

  1. Obtain Consent: Members must actively opt in (e.g., by texting a keyword, checking a box, or verbally confirming)
  2. Record Consent: Track when and how consent was given
  3. Provide Opt-out: Always include opt-out instructions (e.g., "Reply STOP to unsubscribe")

Enable SMS Notifications for a Member

Set notification preferences when creating or updating members:

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 '{
"notifySms": true,
"notifyEmail": true,
"notifyVoice": false
}'

Best Practice: Only enable SMS notifications after obtaining explicit consent.

Handle Opt-in via SMS

When a member texts a keyword like "START" or "YES", mark them as opted in:

// Webhook handler example
app.post('/webhooks/sms-received', async (req, res) => {
const { chatId, message, memberId } = req.body;

// Check if message is an opt-in keyword
if (
message.content.toUpperCase().includes('START') ||
message.content.toUpperCase().includes('YES')
) {
// Enable SMS notifications
await fetch(`https://api.gravityrail.com/api/v2/w/${workspaceUuid}/members/${memberId}`, {
method: 'PUT',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
notifySms: true,
}),
});

// Send confirmation
await fetch(
`https://api.gravityrail.com/api/v2/w/${workspaceUuid}/chats/${chatId}/send-assistant-message`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${apiKey}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
message:
'Thanks for opting in! You will now receive appointment reminders. Reply STOP to unsubscribe.',
}),
}
);
}

res.sendStatus(200);
});

Handle Opt-out (STOP)

Gravity Rail automatically handles STOP keywords. When a member texts "STOP", they are automatically opted out and no further messages will be sent.

Check Delivery Status

Monitor message delivery:

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

Each message includes delivery status:

  • sent - Message queued for delivery
  • delivered - Message successfully delivered
  • failed - Delivery failed (member opted out, invalid number, etc.)

Step 6: Form Webhooks (Getting Data Out)

Webhooks notify your application in real-time when events occur in Gravity Rail.

Configure a Webhook

Webhooks are delivered by Event Rules: each rule pairs one eventType with a webhook:send action. Create one rule per event you want to receive:

curl -X POST https://api.gravityrail.com/api/v2/w/{workspace_uuid}/event-rules \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Send new data records to my app",
"eventType": "data_record:created",
"actionType": "webhook:send",
"actionParams": {
"webhookUrl": "https://your-app.com/webhooks/gravity-rail",
"signingSecret": "whsec_your_secret"
}
}'

Webhook Event Types

Common event types you can subscribe to:

Event typeDescription
data_record:createdNew data record created
data_record:updatedData record updated
member:updatedMember information updated
chat:createdNew chat started
call:startedVoice call started
call:completedVoice call ended
call:summaryCall summary available

Handle Webhook Events

The event type is in the top-level event field, and the payload's other fields sit at the top level (there is no data wrapper):

const express = require('express');

app.post('/webhooks/gravity-rail', (req, res) => {
const payload = req.body;

switch (payload.event) {
case 'data_record:created':
console.log(`New record: ${JSON.stringify(payload.dataRecord.fields)}`);
// Sync form data to your CRM
syncToCRM(payload.dataRecord);
break;

case 'member:updated':
console.log(`Member updated: ${payload.member.email}`);
break;

case 'call:completed':
// Fetch audio/transcript with your own chats:read request
console.log(`Call ended on chat ${payload.chat.id}`);
break;
}

res.sendStatus(200);
});

Webhook Security

  1. Use HTTPS: Webhook URLs must use HTTPS — Gravity Rail rejects http:// in production because payloads can include PHI.
  2. Verify the signature: When a signing secret is configured, each delivery carries an X-Webhook-Signature HMAC-SHA256 header — verify it and reject deliveries older than five minutes.
  3. Idempotency: Handle duplicate webhook deliveries gracefully (failed deliveries are retried).
  4. Respond Quickly: Return a 2xx promptly; non-2xx responses are retried.

For the complete payload field reference and signature-verification code, see the Webhooks reference. For querying delivery history, see Exporting Data.

Step 7: MCP Integration

Model Context Protocol (MCP) allows you to connect AI models like Claude to your Gravity Rail workspace, enabling AI agents to access your data and workflows.

What is MCP?

MCP is a protocol that lets AI models:

  • Read and write Gravity Rail data
  • Create and manage tasks
  • Send messages to members
  • Execute workflow actions
  • Access custom tools you define

Create an MCP OAuth App

To integrate Claude or other MCP clients, create an OAuth application:

  1. Open your account menu (top-right) and go to Account → Apps tab, then the Apps sub-tab
  2. Click Create Application
  3. Fill in the app details:
    • Name: "Claude Integration"
    • MCP Server URL: Your MCP server endpoint (optional)
    • Redirect URIs: OAuth callback URLs
  4. Select required scopes:
    • workspace:read, workspace:write
    • members:read, members:write
    • data:read, data:write
    • chats:read, chats:write
    • task:read, task:write
  5. Save and copy your Client ID and Client Secret

Connect Claude to Your Workspace

Configure Claude Desktop or other MCP clients to connect:

{
"mcpServers": {
"gravity-rail": {
"url": "https://api.gravityrail.com/api/v2/mcp",
"oauth": {
"clientId": "gr_app_...",
"clientSecret": "gr_app_priv_...",
"authorizationUrl": "https://api.gravityrail.com/api/v2/oauth/authorize",
"tokenUrl": "https://api.gravityrail.com/api/v2/oauth/token"
}
}
}
}

MCP Use Cases

Once connected, AI models can:

  • Customer Support: Read customer records, send messages, create tasks
  • Data Entry: Create and update data records via natural language
  • Workflow Automation: Trigger and manage workflows
  • Reporting: Query and analyze workspace data

For complete MCP documentation, see the MCP Integration Guide.

Complete Integration Example

Here's a complete example that ties everything together:

import { GravityRailClient } from '@gravity-rail/sdk';

const API_KEY = process.env.GRAVITY_RAIL_API_KEY;
const BASE_URL = 'https://api.gravityrail.com/api/v2';
const WORKSPACE_UUID = process.env.WORKSPACE_UUID;

const client = new GravityRailClient(API_KEY, BASE_URL);

async function onboardNewPatient(patientData) {
// Step 1: Register the member
const { member, wasCreated } = await client.createSignup(WORKSPACE_UUID, {
member: {
email: patientData.email,
phone: patientData.phone,
name: patientData.name,
},
data: {
patient: {
externalId: `medical_${patientData.patientId}`,
values: {
medical_id: patientData.medicalId,
date_of_birth: patientData.dob,
insurance_provider: patientData.insurance,
},
},
},
});

console.log(`Member ${wasCreated ? 'created' : 'updated'}: ${member.id}`);

// Step 2: Initiate SMS conversation
const chat = await client.createChat(WORKSPACE_UUID, {
channel: 'phone-sms',
phoneNumberId: 123, // Your Gravity Rail phone number
title: `Patient Onboarding: ${patientData.name}`,
});

console.log(`Chat created: ${chat.id}`);

// Step 3: Send welcome message with opt-in
await client.sendAssistantMessage(
WORKSPACE_UUID,
chat.id,
`Hi ${patientData.name}! Welcome to our practice. Reply START to receive appointment reminders and health tips.`
);

console.log('Welcome message sent');

return { member, chat };
}

// Usage
onboardNewPatient({
email: 'patient@example.com',
phone: '+1-555-123-4567',
name: 'Jane Patient',
patientId: 'PAT001',
medicalId: 'MED123456',
dob: '1985-06-15',
insurance: 'Blue Cross',
});

Next Steps

You've now learned the essential integration steps:

  • ✅ Register members with the signup API
  • ✅ Attach custom metadata via data types
  • ✅ Initiate SMS and chat conversations
  • ✅ Handle SMS opt-in and message delivery
  • ✅ Set up webhooks to receive real-time updates
  • ✅ Connect AI models via MCP

Dive Deeper

Common Integration Patterns

  • Healthcare: Patient engagement, appointment reminders, care coordination
  • Customer Support: Multi-channel inbox, AI-powered responses, ticket routing
  • Sales: Lead management, automated follow-ups, pipeline tracking
  • Education: Student communication, assignment reminders, parent notifications

Need Help?

  • Email: support@gravityrail.com
  • Documentation: Browse the sidebar for detailed guides
  • API Reference: Complete endpoint documentation with examples