Outreach
The outreach system manages the flow of messages sent to prospective testers. An AI draft is generated for each candidate, reviewed or edited by the team, then approved for sending. The proposals section covers invitations generated from the matching algorithm.
Endpoints
/api/outreach/queue JWT List all pending outreach messages awaiting review
Returns all outreach messages in pending status, ordered by creation time (oldest first).
Query parameters
| Parameter | Type | Description |
|---|---|---|
jobId | string | Filter queue by study |
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 20) |
Response
{ "success": true, "data": [ { "outreachId": "out_001", "jobId": "job_abc123", "testerId": "user_xyz789", "testerEmail": "tester@example.com", "channel": "email", "subject": "You're a great fit for a new usability study", "body": "Hi Alex, we have a new study on checkout flows that matches your profile...", "status": "pending", "generatedAt": "2026-03-16T08:00:00Z" } ], "error": null, "metadata": { "page": 1, "limit": 20, "total": 7 }}/api/outreach/:id/approve JWT Approve a pending outreach message for sending
Path parameters
| Parameter | Description |
|---|---|
id | Outreach message ID |
Approving queues the message for delivery via the configured channel (email or Telegram).
Request body
None required.
Response
{ "success": true, "data": { "outreachId": "out_001", "status": "approved", "scheduledSendAt": "2026-03-16T09:00:00Z", "approvedAt": "2026-03-16T08:30:00Z" }, "error": null, "metadata": null}/api/outreach/:id/edit JWT Edit and save changes to a pending outreach message
Path parameters
| Parameter | Description |
|---|---|
id | Outreach message ID |
Updates the message content before sending. The message remains in pending status and must be explicitly approved after editing.
Request body
{ "subject": "New study opportunity - 15 min checkout test", "body": "Hi Alex, we're running a quick usability test on our checkout redesign. It takes about 15 minutes and pays $15. Your profile is a great match. Interested?"}| Field | Type | Required | Description |
|---|---|---|---|
subject | string | No | Updated subject line (email only) |
body | string | Yes | Updated message body |
Response
{ "success": true, "data": { "outreachId": "out_001", "status": "pending", "updatedAt": "2026-03-16T08:25:00Z" }, "error": null, "metadata": null}/api/outreach/:id/reject JWT Reject an outreach message to prevent it from being sent
Path parameters
| Parameter | Description |
|---|---|
id | Outreach message ID |
Rejected messages are not sent. Use this when a candidate is no longer eligible or the message content is inappropriate.
Request body
{ "reason": "Tester is currently suspended."}reason is optional but recommended for audit purposes.
Response
{ "success": true, "data": { "outreachId": "out_001", "status": "rejected", "rejectedAt": "2026-03-16T08:20:00Z" }, "error": null, "metadata": null}/api/outreach/proposals JWT List candidate proposals generated by the matching algorithm
Proposals are testers that the matching algorithm has identified as strong candidates for a study, before outreach messages are drafted. Review proposals to confirm or skip candidates before the outreach queue is populated.
Query parameters
| Parameter | Type | Description |
|---|---|---|
jobId | string | Required. Filter proposals by study. |
status | string | Filter by pending, accepted, skipped |
page | integer | Page number (default: 1) |
limit | integer | Results per page (default: 20) |
Response
{ "success": true, "data": [ { "proposalId": "prop_001", "jobId": "job_abc123", "testerId": "user_xyz789", "matchScore": 0.94, "matchReasons": [ "Country matches targeting (IT)", "Age within range (28)", "Device: desktop", "12 prior completed sessions" ], "status": "pending", "generatedAt": "2026-03-16T07:00:00Z" } ], "error": null, "metadata": { "page": 1, "limit": 20, "total": 15 }}/api/outreach/proposals/:id/approve JWT Accept a candidate proposal and queue an outreach message
Path parameters
| Parameter | Description |
|---|---|
id | Proposal ID |
Approving a proposal generates an AI-drafted outreach message and adds it to the pending queue.
Request body
None required.
Response
{ "success": true, "data": { "proposalId": "prop_001", "status": "accepted", "outreachId": "out_002", "acceptedAt": "2026-03-16T08:00:00Z" }, "error": null, "metadata": null}/api/outreach/proposals/:id/reject JWT Skip a candidate proposal without creating an outreach message
Path parameters
| Parameter | Description |
|---|---|
id | Proposal ID |
Request body
{ "reason": "Tester has already participated in a similar study."}Response
{ "success": true, "data": { "proposalId": "prop_001", "status": "skipped", "skippedAt": "2026-03-16T08:00:00Z" }, "error": null, "metadata": null}