Qualifying Interviews
Send qualifying questionnaires to prospects, capture leads from a public URL, and seed product configurations from the answers.
Authorization: Bearer <token> header. Some endpoints require Admin role.Core Endpoints
List all interview templates for the current organization.
Response
List of interview templates
{
"data": [
{
"id": 1,
"organization_id": 1,
"name": "Foxit PDF SDK Qualification",
"slug": "foxit-pdf-sdk",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {},
"created_at": "2026-01-15T09:30:00.000000Z",
"updated_at": "2026-01-15T09:30:00.000000Z"
}
]
}Code Examples
curl -X GET "https://crm.revorbit.com/api/interview-templates" \ -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
"https://crm.revorbit.com/api/interview-templates",
{
method: "GET",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Create a new interview template. Templates are JSON-driven with pages, questions, conditional logic, and field-mapping hints for configurator seeding.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | |
| slug | string | Required | |
| public_slug | string | Optional | Nullable |
| lead_capture_enabled | boolean | Optional | |
| pages | array[object] | Required | |
| questions | array[object] | Required | |
| branding | object | Optional | |
| thank_you | object | Optional | |
| hints | object | Optional |
Response
Template created
{
"id": 1,
"organization_id": 1,
"name": "Foxit PDF SDK Qualification",
"slug": "foxit-pdf-sdk",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {},
"created_at": "2026-01-15T09:30:00.000000Z",
"updated_at": "2026-01-15T09:30:00.000000Z"
}Code Examples
curl -X POST "https://crm.revorbit.com/api/interview-templates" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "...",
"slug": "...",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {}
}'const response = await fetch(
"https://crm.revorbit.com/api/interview-templates",
{
method: "POST",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(
{
"name": "...",
"slug": "...",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {}
}
)
}
);
const data = await response.json();Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Response
Template details
{
"id": 1,
"organization_id": 1,
"name": "Foxit PDF SDK Qualification",
"slug": "foxit-pdf-sdk",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {},
"created_at": "2026-01-15T09:30:00.000000Z",
"updated_at": "2026-01-15T09:30:00.000000Z"
}Code Examples
curl -X GET "https://crm.revorbit.com/api/interview-templates/{id}" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"const response = await fetch(
"https://crm.revorbit.com/api/interview-templates/{id}",
{
method: "GET",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | Required | |
| slug | string | Required | |
| public_slug | string | Optional | Nullable |
| lead_capture_enabled | boolean | Optional | |
| pages | array[object] | Required | |
| questions | array[object] | Required | |
| branding | object | Optional | |
| thank_you | object | Optional | |
| hints | object | Optional |
Code Examples
curl -X PUT "https://crm.revorbit.com/api/interview-templates/{id}" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "...",
"slug": "...",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {}
}'const response = await fetch(
"https://crm.revorbit.com/api/interview-templates/{id}",
{
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(
{
"name": "...",
"slug": "...",
"public_slug": "...",
"lead_capture_enabled": true,
"pages": [
{}
],
"questions": [
{}
],
"branding": {},
"thank_you": {},
"hints": {}
}
)
}
);
const data = await response.json();Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Code Examples
curl -X DELETE "https://crm.revorbit.com/api/interview-templates/{id}" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"const response = await fetch(
"https://crm.revorbit.com/api/interview-templates/{id}",
{
method: "DELETE",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();List invites for the current organization. Optional filters narrow by lead, deal, template, or status.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| lead_id | integer | Optional | |
| deal_id | integer | Optional | |
| template_id | integer | Optional | |
| status | string | Optional | Values: pending, started, submitted, expired |
Response
List of invites
{
"data": [
{
"id": 1,
"organization_id": 1,
"template_id": 1,
"lead_id": 1,
"deal_id": 1,
"token": "...",
"recipient_email": "...",
"recipient_name": "...",
"status": "pending",
"expires_at": "2026-01-15T09:30:00.000000Z",
"sent_at": "2026-01-15T09:30:00.000000Z",
"submitted_at": "2026-01-15T09:30:00.000000Z",
"created_by": 1,
"created_at": "2026-01-15T09:30:00.000000Z"
}
]
}Code Examples
curl -X GET "https://crm.revorbit.com/api/interview-invites" \ -H "Authorization: Bearer YOUR_JWT_TOKEN"
const response = await fetch(
"https://crm.revorbit.com/api/interview-invites",
{
method: "GET",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Create a per-prospect invite with a 64-character random hex token. Optionally sends a branded email via Resend.
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| template_id | integer | Required | |
| lead_id | integer | Optional | Link the invite to an existing lead. If set, the form pre-fills name/email/company.. Nullable |
| deal_id | integer | Optional | Link the invite to an existing deal. Mutually compatible with lead_id.. Nullable |
| recipient_email | string | Required | |
| recipient_name | string | Optional | |
| expires_at | datetime | Optional | Nullable |
| send_email | boolean | Optional | If true, deliver the invite email via Resend with the org's branding. Skipped on dev. |
| personal_note | string | Optional | Optional rep-authored note prepended to the invite email body.. Nullable |
Response
Invite created
{
"id": 1,
"organization_id": 1,
"template_id": 1,
"lead_id": 1,
"deal_id": 1,
"token": "...",
"recipient_email": "...",
"recipient_name": "...",
"status": "pending",
"expires_at": "2026-01-15T09:30:00.000000Z",
"sent_at": "2026-01-15T09:30:00.000000Z",
"submitted_at": "2026-01-15T09:30:00.000000Z",
"created_by": 1,
"created_at": "2026-01-15T09:30:00.000000Z"
}Code Examples
curl -X POST "https://crm.revorbit.com/api/interview-invites" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"template_id": 1,
"lead_id": 1,
"deal_id": 1,
"recipient_email": "...",
"recipient_name": "...",
"expires_at": "2026-01-15T09:30:00.000000Z",
"send_email": true,
"personal_note": "..."
}'const response = await fetch(
"https://crm.revorbit.com/api/interview-invites",
{
method: "POST",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
"Content-Type": "application/json"
},
body: JSON.stringify(
{
"template_id": 1,
"lead_id": 1,
"deal_id": 1,
"recipient_email": "...",
"recipient_name": "...",
"expires_at": "2026-01-15T09:30:00.000000Z",
"send_email": true,
"personal_note": "..."
}
)
}
);
const data = await response.json();Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Response
Invite details
{
"id": 1,
"organization_id": 1,
"template_id": 1,
"lead_id": 1,
"deal_id": 1,
"token": "...",
"recipient_email": "...",
"recipient_name": "...",
"status": "pending",
"expires_at": "2026-01-15T09:30:00.000000Z",
"sent_at": "2026-01-15T09:30:00.000000Z",
"submitted_at": "2026-01-15T09:30:00.000000Z",
"created_by": 1,
"created_at": "2026-01-15T09:30:00.000000Z"
}Code Examples
curl -X GET "https://crm.revorbit.com/api/interview-invites/{id}" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"const response = await fetch(
"https://crm.revorbit.com/api/interview-invites/{id}",
{
method: "GET",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Mark an invite as expired so it can no longer be submitted.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Code Examples
curl -X PUT "https://crm.revorbit.com/api/interview-invites/{id}/expire" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"const response = await fetch(
"https://crm.revorbit.com/api/interview-invites/{id}/expire",
{
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Fetch the submitted answers for an invite, including computed rep flags (e.g. competitive deal, fast timeline, high compliance).
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Response
Submitted answers and rep flags
{
"invite_id": 1,
"template_id": 1,
"status": "started",
"answers": {},
"rep_flags": [
"..."
],
"submitted_at": "2026-01-15T09:30:00.000000Z"
}Code Examples
curl -X GET "https://crm.revorbit.com/api/interview-invites/{id}/responses" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"const response = await fetch(
"https://crm.revorbit.com/api/interview-invites/{id}/responses",
{
method: "GET",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Create a draft Product Configuration on the invite's deal by routing the prospect's `product_line` answer to a configurator definition (slug match) and applying the template's `field_map` rules to extract platform_keys, feature_keys, license_type, and quantity from the submitted answers. Returns the new configuration ID; the wizard can then be opened against it.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| id | integer | Required | Resource ID |
Response
Draft configuration created
{
"configuration_id": 1
}Code Examples
curl -X POST "https://crm.revorbit.com/api/interview-invites/{id}/seed-configuration" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"const response = await fetch(
"https://crm.revorbit.com/api/interview-invites/{id}/seed-configuration",
{
method: "POST",
headers: {
"Authorization": "Bearer YOUR_JWT_TOKEN",
}
}
);
const data = await response.json();Public Interviews
Return the template + any in-progress answers for the prospect's invite. The 64-character hex token in the URL is the only credential. For lead-capture mode (`/public/interview/capture/{slug}`), use the slug variant below. Rate-limited 100 requests / 10 minutes per IP.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| token | string | Required |
Code Examples
curl -X GET "https://crm.revorbit.com/api/public/interview/{token}"const response = await fetch(
"https://crm.revorbit.com/api/public/interview/{token}",
{
method: "GET",
headers: {
}
}
);
const data = await response.json();Persist a partial set of answers without submitting. Called on every change as the prospect fills out the form so they can leave and resume later. Rate-limited 100 requests / 10 minutes per IP.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| token | string | Required |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| answers | object | Optional | Map of question_key → answer value |
Code Examples
curl -X PATCH "https://crm.revorbit.com/api/public/interview/{token}" \
-H "Content-Type: application/json" \
-d '{"answers":{}}'const response = await fetch(
"https://crm.revorbit.com/api/public/interview/{token}",
{
method: "PATCH",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(
{
"answers": {}
}
)
}
);
const data = await response.json();Final submission of the interview. Marks the invite as `submitted`, locks answers from further edits, fires the `interview_submitted` notification to the assigned rep, and (for lead-capture mode) creates a Lead.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| token | string | Required |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| answers | object | Optional | Final answer set (also accepted via prior PATCH calls). |
Code Examples
curl -X POST "https://crm.revorbit.com/api/public/interview/{token}/submit" \
-H "Content-Type: application/json" \
-d '{"answers":{}}'const response = await fetch(
"https://crm.revorbit.com/api/public/interview/{token}/submit",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(
{
"answers": {}
}
)
}
);
const data = await response.json();Return the public lead-capture template by slug. Anyone can submit; on submit a new Lead is created. Optional `?r={user_id}` query param auto-assigns the captured Lead to that rep (validated against `organization_users.seat_active`). Rate-limited 100 requests / 10 minutes per IP.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | Required |
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| r | integer | Optional | Optional user_id to auto-assign the captured lead. Only honored if the user is an active seat in the template's organization. |
Code Examples
curl -X GET "https://crm.revorbit.com/api/public/interview/capture/{slug}"const response = await fetch(
"https://crm.revorbit.com/api/public/interview/capture/{slug}",
{
method: "GET",
headers: {
}
}
);
const data = await response.json();Create a new Lead from the submitted answers and (if `?r={user_id}` was set on the show endpoint) assign it to that rep. Fires the `lead_captured` notification.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | Required |
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| r | integer | Optional | Optional user_id to auto-assign the new Lead. Validated against organization_users.seat_active. |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| answers | object | Optional |
Code Examples
curl -X POST "https://crm.revorbit.com/api/public/interview/capture/{slug}/submit" \
-H "Content-Type: application/json" \
-d '{"answers":{}}'const response = await fetch(
"https://crm.revorbit.com/api/public/interview/capture/{slug}/submit",
{
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(
{
"answers": {}
}
)
}
);
const data = await response.json();