TextConvo Docs

    Everything you need to integrate TextConvo — API reference, CRM guides, and webhook documentation.

    Last updated: April 2026

    Introduction

    TextConvo provides a suite of APIs to ingest leads, send SMS messages, receive replies, and automate conversations using AI-powered workflows.

    Base URL

    https://api.textconvo.ai

    Quick Start

    Try your first API call right away. Replace YOUR_API_KEY with your actual key.

    bash
    curl -X POST https://api.textconvo.ai/functions/v1/ingest-lead \
      -H "Content-Type: application/json" \
      -H "X-API-Key: YOUR_API_KEY" \
      -d '{
        "first_name": "John",
        "last_name": "Doe",
        "phone": "+15035551234",
        "email": "john@example.com"
      }'

    Authentication

    All API requests must include your API key in the request headers.

    Required Header

    X-API-Key: YOUR_API_KEY
    http
    POST /functions/v1/ingest-lead
    Content-Type: application/json
    X-API-Key: YOUR_API_KEY

    HMAC Authentication

    TextConvo supports optional HMAC request signing for enhanced security. This ensures requests are not tampered with in transit.

    Steps

    1. Generate a Unix timestamp.
    2. Create a signature using HMAC SHA-256 with your API secret.
    3. Send the signature in request headers.

    Required Headers

    X-API-KeyX-TimestampX-Signature

    Signature Formula

    text
    HMAC_SHA256(
      timestamp + request_body,
      API_SECRET
    )

    Example Request

    bash
    curl -X POST https://api.textconvo.ai/functions/v1/ingest-lead \
      -H "Content-Type: application/json" \
      -H "X-API-Key: tc_live_xxxxx" \
      -H "X-Timestamp: 1710000000" \
      -H "X-Signature: generated_signature" \
      -d '{
        "first_name": "John",
        "phone": "+15035551234"
      }'

    Note: HMAC signing is recommended for enterprise integrations.

    Lead Ingestion API

    POST/functions/v1/ingest-lead

    Create a new lead inside TextConvo. The lead will be matched to an existing contact by phone number or created as a new contact. A journey will be queued automatically based on your account configuration.

    Request Headers

    HeaderRequiredDescription
    X-API-KeyYesYour TextConvo API key
    Content-TypeYesapplication/json
    X-TimestampNoUnix timestamp for HMAC
    X-SignatureNoHMAC-SHA256 signature

    Request Body

    json
    {
      "lead_external_id": "string — your CRM's ID for this lead",
      "first_name": "string",
      "last_name": "string",
      "email": "string",
      "phone": "string — E.164 format e.g. +15035551234",
      "company": "string (optional)",
      "lead_source": "string (optional)",
      "custom_fields": {
        "any_key": "any_value"
      }
    }

    Required fields: phone is required.

    Success Response

    json
    {
      "success": true,
      "lead_id": "lead_abc123",
      "contact_id": "cnt_xyz789",
      "status": "queued"
    }

    Error Response

    json
    {
      "success": false,
      "error": "phone is required",
      "code": "MISSING_REQUIRED_FIELD"
    }

    Contacts API

    GET/functions/v1/contacts/{contact_id}

    Retrieve a contact and their latest inquiry by contact ID.

    Example Request

    bash
    curl -X GET https://api.textconvo.ai/functions/v1/contacts/cnt_xyz789 \
      -H "X-API-Key: YOUR_API_KEY"

    Response

    json
    {
      "contact_id": "cnt_xyz789",
      "phone": "+15035551234",
      "email": "john@example.com",
      "created_at": "2026-04-20T10:00:00Z",
      "latest_inquiry": {
        "id": "inq_abc123",
        "lead_source": "hubspot",
        "created_at": "2026-04-20T10:00:00Z",
        "status": "completed"
      }
    }

    Webhooks

    TextConvo can send webhook events when SMS activity occurs.

    Supported Events

    • sms.delivered— Message delivered to carrier
    • sms.failed— Message failed to deliver
    • sms.reply— Contact replied to a message
    • journey.started— Journey began for a contact
    • journey.completed— Journey finished
    • journey.opted_out— Contact opted out
    • contact.created— New contact created

    Payload Structures

    sms.delivered

    json
    {
      "event": "sms.delivered",
      "message_id": "msg_abc123",
      "contact_id": "cnt_xyz789",
      "lead_id": "lead_abc123",
      "phone": "+15035551234",
      "provider": "twilio",
      "delivered_at": "2026-04-20T10:12:00Z"
    }

    sms.failed

    json
    {
      "event": "sms.failed",
      "message_id": "msg_abc123",
      "contact_id": "cnt_xyz789",
      "lead_id": "lead_abc123",
      "phone": "+15035551234",
      "error": "carrier_rejected",
      "failed_at": "2026-04-20T10:12:00Z"
    }

    sms.reply

    json
    {
      "event": "sms.reply",
      "message_id": "msg_reply123",
      "contact_id": "cnt_xyz789",
      "lead_id": "lead_abc123",
      "phone": "+15035551234",
      "message": "Yes send quote",
      "received_at": "2026-04-20T10:18:00Z"
    }

    journey.started

    json
    {
      "event": "journey.started",
      "contact_id": "cnt_xyz789",
      "lead_id": "lead_abc123",
      "journey_queue_id": "jq_def456",
      "started_at": "2026-04-20T10:00:00Z",
      "metadata": {
        "lead_source": "hubspot",
        "entry_step": "initial_outreach"
      }
    }

    journey.completed

    json
    {
      "event": "journey.completed",
      "contact_id": "cnt_xyz789",
      "lead_id": "lead_abc123",
      "journey_queue_id": "jq_def456",
      "outcome": "completed",
      "completed_at": "2026-04-20T11:30:00Z",
      "metadata": {
        "messages_sent": 3,
        "replies_received": 2,
        "duration_minutes": 45
      }
    }

    journey.opted_out

    json
    {
      "event": "journey.opted_out",
      "contact_id": "cnt_xyz789",
      "lead_id": "lead_abc123",
      "journey_queue_id": "jq_def456",
      "opted_out_at": "2026-04-20T10:25:00Z",
      "metadata": {
        "keyword": "STOP",
        "channel": "sms"
      }
    }

    contact.created

    json
    {
      "event": "contact.created",
      "contact_id": "cnt_xyz789",
      "phone": "+15035551234",
      "email": "john@example.com",
      "first_name": "John",
      "last_name": "Doe",
      "created_at": "2026-04-20T10:00:00Z"
    }

    Webhook Security

    All webhooks from TextConvo include an X-TextConvo-Signature header. Verify it using HMAC-SHA256 with your webhook secret.

    javascript
    const crypto = require('crypto');
    const signature = req.headers['x-textconvo-signature'];
    const computed = crypto
      .createHmac('sha256', process.env.WEBHOOK_SECRET)
      .update(JSON.stringify(req.body))
      .digest('hex');
    const isValid = signature === computed;

    Rate Limits

    PlanRequests per minuteDaily limit
    Starter6010,000
    Professional300100,000
    EnterpriseCustomUnlimited

    Response Headers

    Rate limit headers are returned on every response.

    http
    X-RateLimit-Limit: 60
    X-RateLimit-Remaining: 45
    X-RateLimit-Reset: 1714000000

    Limit Exceeded

    When exceeded, TextConvo returns 429.

    json
    {
      "error": "Rate limit exceeded",
      "retry_after": 30
    }

    Error Codes

    CodeDescription
    400Bad Request — Invalid parameters
    401Unauthorized — Invalid API key
    403Forbidden — Insufficient permissions
    429Rate Limit — Too many requests
    500Server Error — Internal error

    CRM Integrations

    Overview

    TextConvo supports bi-directional CRM integration. Your CRM sends leads via webhook, TextConvo runs the journey, and pushes results back automatically.

    CRM → Webhook → TextConvo → Journey → Push results back → CRM

    HubSpot Integration Guide

    Prerequisites

    • HubSpot account (any paid plan)
    • TextConvo account with API access
    • Super Admin access in HubSpot

    Step 1 — Create a Legacy App in HubSpot

    1. Go to app-na2.hubspot.com
    2. Click Settings (gear icon) → Integrations → Legacy Apps
    3. Click "Create legacy app" → Select "Private"
    4. Name it "TextConvo"
    5. Go to Scopes tab and add crm.objects.contacts.read and crm.objects.contacts.write
    6. Click "Create app"
    7. Go to Auth tab → click "Show token"
    8. Copy your Access Token (starts with pat-)

    Step 2 — Create custom contact properties

    In HubSpot → Settings → Data Management → Properties → Contact properties → Create property:

    Property labelInternal nameField type
    TextConvo Journey Statustextconvo_journey_statusSingle-line text
    TextConvo Journey Datetextconvo_journey_dateDate picker
    TextConvo Outcometextconvo_outcomeSingle-line text
    TextConvo Notestextconvo_notesMulti-line text

    Step 3 — Connect in TextConvo

    1. Go to Integrations → CRM Connectors → HubSpot
    2. Click "Connect"
    3. Paste your Access Token (pat-na2-...)
    4. Paste your Webhook Client Secret (found in HubSpot → Settings → Integrations → Private Apps → your app → Auth tab → Client Secret)
    5. Review field mappings (defaults are recommended)
    6. Select outbound events to sync back
    7. Click "Save & Activate"

    Step 4 — Configure HubSpot webhook

    1. In your HubSpot app → Webhooks tab
    2. Set Target URL to your TextConvo webhook URL:
      1. In TextConvo → Integrations → CRM Connectors → HubSpot → Manage
      2. Copy the Webhook URL shown at the top
      3. Paste it into HubSpot as the Target URL
    1. Subscribe to Contact → Created and Contact → Property changed events
    2. Include properties: firstname, lastname, phone, email, company
    3. Click Subscribe

    Step 5 — Test the integration

    1. Create a test contact in HubSpot with a phone number
    2. Check TextConvo → Integrations → HubSpot → Webhook logs
    3. Verify contact appears in TextConvo contacts
    4. Check HubSpot contact for TextConvo properties after journey completes

    Field Mapping Reference

    HubSpot fieldTextConvo field
    firstnamefirst_name
    lastnamelast_name
    phonephone (required)
    emailemail
    companycompany
    hs_lead_sourcelead_source

    Troubleshooting

    IssueSolution
    Webhook logs show “Invalid signature”Check Client Secret is correct in TextConvo
    Contact created but no journeyPhone number missing on HubSpot contact
    Push fails with 400Custom HubSpot properties not created (Step 2)
    Push fails with 401Access Token expired — reconnect in TextConvo

    HubSpot Integration FAQ

    GoHighLevel Integration Guide

    Prerequisites

    • GoHighLevel account (any Agency plan)
    • TextConvo account with API access
    • Super Admin access in TextConvo

    Step 1 — Create a Private Integration Token in GHL

    1. Log into GHL and switch to your Sub-Account
    2. Go to Settings → Private Integrations → Create New Integration
    3. Name it "TextConvo"
    4. Select these scopes:
      • contacts.readonly
      • contacts.write
      • locations.readonly
    5. Click Create and copy the token immediately (starts with pit-)

    You cannot view this token again after leaving the page.

    Step 2 — Find your Location ID

    1. In GHL, switch to your Sub-Account
    2. Look at the URL in your browser:
    text
    app.gohighlevel.com/location/{YOUR_LOCATION_ID}/dashboard

    Copy the Location ID from the URL.

    Step 3 — Create custom contact fields in GHL

    In GHL → Settings → Custom Fields → Add Field (type: Text) for each:

    Field KeyPurpose
    textconvo_journey_statusJourney completion status
    textconvo_journey_outcomeJourney outcome (qualified, not interested etc)
    textconvo_reentry_tokenTriggers re-entry into a new journey

    Step 4 — Connect in TextConvo

    1. Go to Integrations → CRM Connectors → GoHighLevel
    2. Click "Connect"
    3. Select your Account
    4. Paste your Private Integration Token (pit-xxx)
    5. Paste your Sub-Account Location ID
    6. Review field mappings (defaults recommended)
    7. Select outbound events to sync back
    8. Click "Save & Activate"

    Step 5 — Set up TWO GHL Workflows

    GHL uses Workflows to send webhooks. You need two separate workflows.

    Get your Webhook URL first: TextConvo → Integrations → CRM Connectors → GoHighLevel → Manage → copy the Webhook URL.

    Workflow 1 — New Contacts

    1. GHL → Automation → Workflows → Create Workflow → Start from Scratch
    2. Add Trigger: Contact Created (no filters needed)
    3. Add Action: Webhook
      • Method: POST
      • URL: paste your TextConvo Webhook URL copied above
    4. Save and click Publish

    Workflow 2 — Contact Updates

    1. GHL → Automation → Workflows → Create Workflow → Start from Scratch
    2. Add Trigger: Contact Changed (no filters needed)
    3. Add Action: Webhook
      • Method: POST
      • URL: paste the same TextConvo Webhook URL
    4. Save and click Publish

    Step 6 — Test the integration

    1. Create a test contact in GHL with a phone number
    2. Check TextConvo → Inquiries — contact should appear within seconds with SOURCE = GoHighLevel
    3. Update a field on the GHL contact
    4. Check the Activity Timeline in TextConvo — should show "GoHighLevel contact updated" with the changed field

    Field Mapping Reference

    GoHighLevel fieldTextConvo field
    firstNamefirst_name
    lastNamelast_name
    phonephone (required)
    emailemail
    sourcelead_source
    tagstags

    Troubleshooting

    IssueSolution
    No contacts appearing after creationConfirm Workflow 1 (Contact Created) is Published
    No timeline events on field changesConfirm Workflow 2 (Contact Changed) is Published
    Test connection fails with 401Token invalid — recreate Private Integration in GHL
    Test connection fails with 404Location ID incorrect — check URL in GHL sub-account
    SOURCE shows as “gohighlevel” not “GoHighLevel”Reconnect the integration — display name fix is live

    GoHighLevel Integration FAQ

    Zoho CRM Integration Guide

    Prerequisites

    • Zoho CRM account (any paid plan)
    • TextConvo account with API access
    • Super Admin access in TextConvo

    Step 1 — Generate an OAuth Access Token

    For testing, use the Self Client method:

    1. Go to api-console.zoho.com
    2. Click "Self Client"
    3. Click "Generate Code"
    4. In the Scope field paste:
      text
      ZohoCRM.modules.contacts.ALL,ZohoCRM.org.READ,ZohoCRM.modules.notes.CREATE
    5. Set duration to 10 minutes
    6. Click Create — copy the token immediately (starts with 1000.)

    For production use, create a Server-based OAuth app to get a refresh token that never expires. Self Client tokens expire in 10 minutes.

    Step 2 — Connect in TextConvo

    1. Go to Integrations → CRM Connectors → Zoho CRM
    2. Click Connect
    3. Select your Account
    4. Paste your OAuth Access Token (starts with 1000.)
    5. Enter any value for Webhook Secret (e.g. test123) — optional for testing
    6. Review field mappings (defaults recommended)
    7. Select outbound events to sync back
    8. Click Save & Activate

    Get your Webhook URL from: TextConvo → Integrations → CRM Connectors → Zoho CRM → Manage → Webhook URL.

    Step 3 — Create TWO Workflow Rules in Zoho CRM

    Zoho sends webhooks via Workflow Rules. You need two separate rules.

    Rule 1 — New Contacts

    1. Zoho CRM → Setup → Automation → Workflow Rules → Create Rule
    2. Module: Contacts
    3. Rule Name: TextConvo — Contact Created
    4. Execute On: Record Action → Create
    5. Condition: All Contacts → Done
    6. Instant Action: Webhook
      • URL: paste your TextConvo Webhook URL
      • Method: POST
      • Body Type: Raw → Format: JSON
      • Body:
    json
    {
      "contact_id": "${!Contacts.id}",
      "First_Name": "${!Contacts.First_Name}",
      "Last_Name": "${!Contacts.Last_Name}",
      "Phone": "${!Contacts.Phone}",
      "Mobile": "${!Contacts.Mobile}",
      "Email": "${!Contacts.Email}",
      "operation": "insert"
    }
    1. Save and Associate → Activate the rule

    Rule 2 — Contact Updates

    1. Create another Workflow Rule
    2. Module: Contacts
    3. Rule Name: TextConvo — Contact Updated
    4. Execute On: Record Action → Edit
    5. Condition: All Contacts → Done
    6. Instant Action: Webhook
      • URL: same TextConvo Webhook URL
      • Method: POST
      • Body Type: Raw → Format: JSON
      • Body:
    json
    {
      "contact_id": "${!Contacts.id}",
      "First_Name": "${!Contacts.First_Name}",
      "Last_Name": "${!Contacts.Last_Name}",
      "Phone": "${!Contacts.Phone}",
      "Mobile": "${!Contacts.Mobile}",
      "Email": "${!Contacts.Email}",
      "operation": "update"
    }
    1. Save and Associate → Activate the rule

    Important: The merge field syntax requires ${!Contacts.field_name} with the exclamation mark and underscores. Spaces in field names are not supported.

    Step 4 — Create custom fields in Zoho for outbound sync

    In Zoho CRM → Setup → Customization → Modules → Contacts → Fields → Add Custom Field (type: Single Line Text):

    • Field name: TextConvo_Journey_Status
    • Field name: TextConvo_Journey_Outcome

    Step 5 — Test the integration

    1. Create a new contact in Zoho CRM with a phone number (include country code e.g. +1)
    2. Check TextConvo → Inquiries — contact should appear within seconds with SOURCE = Zoho
    3. Edit a field on that same contact (e.g. change first name)
    4. Check the Activity Timeline in TextConvo — should show "Zoho contact updated" with the changed field

    Field Mapping Reference

    Zoho CRM fieldTextConvo field
    First_Namefirst_name
    Last_Namelast_name
    Phonephone (required)
    Emailemail
    Lead_Sourcelead_source

    Important Notes

    • OAuth tokens from Self Client expire in 10 minutes (testing only)
    • For production, use a Server-based OAuth app to get a non-expiring refresh token
    • Two workflow rules are required — one for Create, one for Edit
    • Merge fields must use ${!Contacts.field_name} syntax with ! and underscores
    • Zoho limits webhooks to 10 fields maximum per notification

    Troubleshooting

    IssueSolution
    No contacts appearingConfirm Rule 1 (Create) is Active in Zoho
    No timeline events on editsConfirm Rule 2 (Edit) is Active and body has operation=update
    Connection invalid after 10 minOAuth token expired — regenerate from api-console.zoho.com
    Duplicate inquiries on editCheck Rule 2 body — operation must be "update" not "insert"
    Merge field error on saveUse ${!Contacts.First_Name} syntax — exclamation mark required
    Test connection fails 401Token expired — generate a new one from Self Client

    Zoho CRM Integration FAQ

    Pipedrive

    Coming soon

    Documentation coming soon. Contact us to join the early access list.

    Contact us

    Zendesk

    Coming soon

    Documentation coming soon. Contact us to join the early access list.

    Contact us

    Salesforce

    Coming soon

    Documentation coming soon. Contact us to join the early access list.

    Contact us

    Push Journey Results

    POST/functions/v1/push-hubspot

    Manually trigger a journey result to be pushed back to HubSpot. This is called automatically by TextConvo when a journey completes, but can also be called manually.

    Request Body

    json
    {
      "contact_id": "cnt_xyz789",
      "account_id": "uuid",
      "outcome": "completed | opted_out | no_response",
      "notes": "optional string"
    }

    Response

    json
    {
      "status": "success",
      "hubspot_contact_id": "473031564003"
    }