Leads & tickets
Capture leads from chat, export them, and manage the tickets escalation creates.
7 endpoints. 2 are reachable without a dashboard session — they are listed in the Integration API — and the other 5 require a Cognito JWT. The badge under each path says which.
/v1/projects/{projectId}/leads Record a lead captured by the widget's contact form.
Auth Integration key
Before you call it
- The project needs
leadCaptureEnabled, and the body needsvisitorIdplus at least one ofnameoremail. - Built-in lead fields are unlimited on every plan — there is no monthly cap.
customFieldsneeds the Growth plan or above withleadFormFieldsconfigured on the project.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Everything it needs is in the request body.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
visitorId | string | Required | Stable identifier for the end user. |
name | string | Optional | Display name. |
email | string | Optional | Email address. |
conversationId | string | Optional | Conversation this relates to. |
sourceQuestion | string | Optional | The question that triggered capture, for context in the dashboard. |
customFields | object | Optional | Values for any custom lead form fields configured on the project. |
Request
{
"visitorId": "visitor_001",
"name": "Jane Doe",
"email": "jane@example.com",
"conversationId": "conv_xyz789",
"customFields": {
"company_size": "50-200",
"plan_tier": "Growth"
}
} Response
200 Success
{ "leadId": "lead_abc123" } Status codes
| Status | Meaning |
|---|---|
| 201 | Created. The body is { leadId }. |
| 400 | The request body failed validation. |
| 401 | Missing, revoked, or wrong-environment key. |
| 402 | customFields were sent on the Free plan. |
| 403 | Origin or IP not allowed for this project. |
| 404 | No such resource in this workspace. |
| 429 | More than 10 submissions from one visitor within an hour. |
curl
curl -X POST 'https://api.dev.oprag.ai/v1/projects/{projectId}/leads' \
-H 'X-Oprag-Key: sk_live_...' \
-H 'Content-Type: application/json' \
-d '{"visitorId": "visitor_001","name": "Jane Doe","email": "jane@example.com","conversationId": "conv_xyz789","customFields": {"company_size": "50-200","plan_tier": "Growth"}}' SDK equivalent `oprag.leads.create()`
/v1/projects/{projectId}/leads List project leads (latest 100). Returns { leads, total }.
Auth Cognito JWT admin
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Neither paginated nor filtered from the query string.
Body parameters
None.GET requests carry no body.
Response
200 Success
{
"leads": [
{
"leadId": "lead_abc123",
"projectId": "proj_abc123",
"visitorId": "visitor_001",
"name": "Jane Doe",
"email": "jane@example.com",
"customFields": {
"company_size": "50-200"
},
"createdAt": "2026-07-09T12:00:00.000Z"
}
],
"total": 1
} Status codes
curl
curl -X GET 'https://api.dev.oprag.ai/v1/projects/{projectId}/leads' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/leads/export Export leads as CSV (text/csv, up to 5 000 rows).
Auth Cognito JWT admin
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Neither paginated nor filtered from the query string.
Body parameters
None.GET requests carry no body.
Response
Status codes
curl
curl -X GET 'https://api.dev.oprag.ai/v1/projects/{projectId}/leads/export' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/lead-alert-webhook/test Send a synthetic lead alert to the project's configured lead-alert webhook.
Auth Cognito JWT admin · Growth+
Before you call it
- Use it to prove the endpoint works before real leads start arriving.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Acts on the resource named in the path; there is nothing to choose.
Body parameters
None.Sends a synthetic alert to the webhook already configured on the project.
Response
200 Success
{
"ok": true
} Status codes
curl
curl -X POST 'https://api.dev.oprag.ai/v1/projects/{projectId}/lead-alert-webhook/test' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/tickets Create an escalation ticket from a conversation.
Auth Integration key
Before you call it
- Delivery is the same as
escalate— webhook, email, or both.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Everything it needs is in the request body.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversationId | string | Required | Conversation the ticket is raised from. |
visitorId | string | Optional | Stable identifier for the end user. |
subject | string | Optional | Short summary line. |
requesterEmail | string | Optional | Email to reply to. |
requesterName | string | Optional | Name of the person asking. |
message | string | Optional | Body text. |
Request
{
"conversationId": "conv_abc123",
"visitorId": "visitor_001",
"subject": "Billing question"
} Response
200 Success
{ "ticketId": "tkt_abc123", "escalated": true } Status codes
| Status | Meaning |
|---|---|
| 200 | Free plan — the escalation was delivered but no ticket is stored: { escalated: true }. |
| 201 | Growth and above — a native ticket was stored: { ticketId, escalated: true }. |
| 400 | The request body failed validation. |
| 401 | Missing, revoked, or wrong-environment key. |
| 403 | Origin or IP not allowed for this project. |
| 404 | No such resource in this workspace. |
| 429 | Rate limited. See rate limits. |
curl
curl -X POST 'https://api.dev.oprag.ai/v1/projects/{projectId}/tickets' \
-H 'X-Oprag-Key: sk_live_...' \
-H 'Content-Type: application/json' \
-d '{"conversationId": "conv_abc123","visitorId": "visitor_001","subject": "Billing question"}' /v1/projects/{projectId}/tickets List project escalation tickets (latest 100). Returns { tickets, total }.
Auth Cognito JWT admin
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Neither paginated nor filtered from the query string.
Body parameters
None.GET requests carry no body.
Response
200 Success
{
"tickets": [
{
"ticketId": "tkt_abc123",
"projectId": "proj_abc123",
"conversationId": "conv_abc123",
"status": "open",
"subject": "Billing question",
"visitorId": "visitor_001",
"createdAt": "2026-06-01T12:00:00.000Z",
"updatedAt": "2026-06-01T12:00:00.000Z"
}
],
"total": 1
} Status codes
curl
curl -X GET 'https://api.dev.oprag.ai/v1/projects/{projectId}/tickets' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/tickets/{ticketId} Update an escalation ticket.
Auth Cognito JWT admin
Before you call it
- The body needs at least one of
status,assigneeUserId, orsubject. - Resolving a ticket emits
ticket.resolved. - The response is
{ ticket }.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
ticketId | string | Required | Ticket within the project. |
Query parameters
None.Everything it needs is in the request body.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
status | "open" | "resolved" | Optional | open or resolved. |
assigneeUserId | string | Optional | Workspace member who owns the ticket. |
subject | string | Optional | Short summary line. |
Request
{ "status": "resolved", "assigneeUserId": "user_abc123" } Response
200 Success
{
"ticket": {
"ticketId": "tkt_abc123",
"status": "resolved",
"resolvedAt": "2026-06-02T09:00:00.000Z",
"assigneeUserId": "user_abc123"
}
} Status codes
curl
curl -X PATCH 'https://api.dev.oprag.ai/v1/projects/{projectId}/tickets/{ticketId}' \
-H 'Authorization: Bearer <Cognito JWT>' \
-H 'Content-Type: application/json' \
-d '{ "status": "resolved", "assigneeUserId": "user_abc123" }' Ready to ship?
Get started free