Skip to content
Video IntrosDevelopers
TestLive not yet available
videointros.com

Preview Developer preview. The API described here is not available yet. Examples are illustrative and every console screen uses sample data: nothing is sent, created or stored.

Touchpoints · Best for CRM integrations

Trigger a touchpoint

POST/v1/touchpoint-events

Send the moment, not the workflow. Video Intros finds the organization's touchpoint and from its configuration decides the script, the page and what happens next. Your integration does not choose a template or write instructions.

Authentication

A bearer API key. Authentication.

Headers

  • Authorizationstringrequired

    Bearer followed by your API key. A test key works in the test environment only.

  • Idempotency-Keystringrequired

    A value that is the same every time you send THIS event, and different for every other event.

  • Content-Typestringrequired

    application/json

Request body

  • touchpointstringrequired

    The slug of one of the organization's touchpoints, from GET /v1/touchpoints.

  • occurred_atstringrequired

    When the moment happened in your system. ISO 8601.

  • memberobjectrequired

    The person on your team who records the video. Identify them by any one of these; Video Intros resolves the member in the organization.

    3 fields in member
    • idstring

      The member's Video Intros identifier, from GET /v1/members.

    • external_idstring

      Your own identifier for this person, as stored on the member.

    • emailstring

      The member's email address. If more than one member has it, the request is refused with member_ambiguous.

  • recipientobjectrequired

    The customer the Video Intro is for.

    3 fields in recipient
    • first_namestringrequired

      Used in the script and on the page.

    • last_namestring

      Optional.

    • phonestringrequired

      Mobile number in E.164 form, for example +12405550100.

  • referenceobject

    The record in your system this is about. Stored with the Video Intro and returned on every event, so you can match it back.

    3 fields in reference
    • sourcestring

      The system the record lives in, for example your_crm.

    • typestring

      What kind of record: appointment, job, deal, contact.

    • idstring

      Its identifier in that system.

  • contextobject

    Facts about the moment that the touchpoint can use.

    3 fields in context
    • appointmentobject

      When the moment has a date and time.

      2 fields in appointment
      • starts_atstring

        ISO 8601 date and time.

      • timezonestring

        IANA time zone, for example America/New_York.

    • tradestring

      Exterior remodeling: roofing, siding, windows, doors or gutters.

    • lanestring

      Exterior remodeling: retail or insurance.

  • metadataobject

    Up to a few of your own key and value pairs. Stored and returned, never interpreted.

Errors

StatusCodeWhen
401
unauthorized
The API key is missing, malformed or revoked.
409
idempotency_conflict
This Idempotency-Key was already used with a different body.
422
validation_failed
A required field is missing or malformed. The response names the field.
422
touchpoint_not_found
The organization has no touchpoint with that slug, or it is turned off.
422
member_not_found
No active member matches the member you named.
422
member_ambiguous
More than one member has that email address. Send the member's id or external_id instead.
429
rate_limited
Too many requests. Wait for the time in Retry-After and send again with the same Idempotency-Key.

All errors

Request
curl -X POST https://api.videointros.com/v1/touchpoint-events \
  -H "Authorization: Bearer $VIDEO_INTROS_API_KEY" \
  -H "Idempotency-Key: your_crm:appointment_123:new_appointment" \
  -H "Content-Type: application/json" \
  -d '{
  "touchpoint": "new_appointment",
  "occurred_at": "2026-10-05T17:40:00Z",
  "member": {
    "external_id": "rep_456"
  },
  "recipient": {
    "first_name": "Andrea",
    "last_name": "Smith",
    "phone": "+12405550100"
  },
  "reference": {
    "source": "your_crm",
    "type": "appointment",
    "id": "appointment_123"
  },
  "context": {
    "appointment": {
      "starts_at": "2026-10-06T18:00:00Z",
      "timezone": "America/New_York"
    }
  },
  "metadata": {
    "job_id": "job_789"
  }
}'
const response = await fetch("https://api.videointros.com/v1/touchpoint-events", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.VIDEO_INTROS_API_KEY}`,
    "Idempotency-Key": "your_crm:appointment_123:new_appointment",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "touchpoint": "new_appointment",
    "occurred_at": "2026-10-05T17:40:00Z",
    "member": {
      "external_id": "rep_456"
    },
    "recipient": {
      "first_name": "Andrea",
      "last_name": "Smith",
      "phone": "+12405550100"
    },
    "reference": {
      "source": "your_crm",
      "type": "appointment",
      "id": "appointment_123"
    },
    "context": {
      "appointment": {
        "starts_at": "2026-10-06T18:00:00Z",
        "timezone": "America/New_York"
      }
    },
    "metadata": {
      "job_id": "job_789"
    }
  }),
});
const result = await response.json();
import os, requests

response = requests.post(
    "https://api.videointros.com/v1/touchpoint-events",
    headers={
        "Authorization": f"Bearer {os.environ['VIDEO_INTROS_API_KEY']}",
        "Idempotency-Key": "your_crm:appointment_123:new_appointment",
    },
    json={
        "touchpoint": "new_appointment",
        "occurred_at": "2026-10-05T17:40:00Z",
        "member": {
            "external_id": "rep_456",
        },
        "recipient": {
            "first_name": "Andrea",
            "last_name": "Smith",
            "phone": "+12405550100",
        },
        "reference": {
            "source": "your_crm",
            "type": "appointment",
            "id": "appointment_123",
        },
        "context": {
            "appointment": {
                "starts_at": "2026-10-06T18:00:00Z",
                "timezone": "America/New_York",
            },
        },
        "metadata": {
            "job_id": "job_789",
        },
    },
)
result = response.json()
Response · 202
{
  "id": "evt_8f3c2a71d04e",
  "object": "touchpoint_event",
  "status": "accepted",
  "touchpoint": "new_appointment",
  "environment": "test",
  "created_at": "2026-10-05T17:40:01Z"
}
An error
{
  "error": {
    "code": "idempotency_conflict",
    "message": "This Idempotency-Key was already used with a different body."
  }
}