Automate data-collection projects without creating a fragile workflow
Use the Connect API to start projects when work is ready, check progress, review results, pay participants, send messages, and invite your best reviewers to future projects.
Your system decides when work should begin. Connect finds participants, collects their answers, and tracks review and payment.
- Retries
- No duplicates
- Progress
- Easy to check
- Results
- Linked to inputs
Common automations
Choose what should happen automatically
For each automation, create one manageable Connect project, save its project ID, and check its current status before moving to the next step.
Start a project when a batch of items is ready
Create the project as unpublished, preview a few items to confirm they look right, then launch immediately or schedule it for later.
create → preview → launchAsk more people to review uncertain items
Choose how many reviewers should see each item, compare their answers, and send items with disagreement through another round.
items → reviews → agreementHave people rate your model's answers
Show model outputs without identifying the model, collect ratings or side-by-side choices, and match each result to the original item ID.
outputs → ratings → scoresApprove good work and send bonuses
Approve or reject work by participant or assignment ID. Give each bonus request a unique token so a retry cannot pay twice.
review → approve → bonusInvite your best reviewers to future projects
Add successful participants to a reusable group, then limit follow-up projects to that group when you need experienced reviewers.
review → group → invite againKeep participants informed when plans change
Send a message to one participant or everyone in a project, with each conversation linked to the correct Connect participant.
change → message → responseHow systems connect
Save Connect IDs with the related records in your system
Identifies the project when you check progress, retrieve answers, review work, or send messages.
Identifies one participant's work so you can match the answer to your item and record the review decision.
Identifies the person when you review work, invite them again, add them to a group, or send a message.
Identifies one API request. Save it when a request fails so Connect support can find what happened.
Before the examples
Create one authenticated client for every request
Every Connect API request must include your API key in the X-API-KEY header. Create and manage keys from the API Keys page in Connect, then create one authenticated session and reuse it for every call. Each Python example on this page assumes this setup has already run.
import os
import requests
api = requests.Session()
api.headers.update({
"X-API-KEY": os.environ["CONNECT_API_KEY"],
"Content-Type": "application/json",
})
Values such as project_payload and process(...) in the examples below are placeholders for your application's own data and code. See the AI data guide for a complete project payload.
Safe retries
Prevent duplicate projects, edits, and payments
Every request that changes data should carry an IDEMPOTENCY-TOKEN header: a unique ID you make up for that one action. If Connect receives the same token again, it does not repeat the action — it returns the result of the first attempt.
That only protects you if the token survives a crash. The example below keeps the token in a small file next to the script, and the file answers one question: did the last attempt get an answer?
If the file already has a token, the last run never got an answer — send that same token again so the action cannot happen twice. Otherwise create a new token and save it to the file first, then send it.
Delete the file only after your code has recorded the outcome — for a created project, its project ID. If the process dies before that, rerunning with the saved token returns the same stored response, so nothing runs twice and the ID is recovered.
The file stays. Nobody knows whether the action happened, and that is exactly when the next run must reuse the saved token.
import uuid
TOKEN_FILE = "create_project.token"
# A leftover token means the last run never got an answer: retry with it.
if os.path.exists(TOKEN_FILE):
with open(TOKEN_FILE) as f:
operation_token = f.read()
else:
operation_token = str(uuid.uuid4())
with open(TOKEN_FILE, "w") as f:
f.write(operation_token)
response = api.post(
"https://connect-api.cloudresearch.com/api/v1/project",
headers={"IDEMPOTENCY-TOKEN": operation_token},
json=project_payload,
timeout=30,
)
# Save both values before starting the next step.
trace_id = response.headers.get("X-TRACE-ID")
response.raise_for_status()
project_id = response.json()["project"]["projectId"]
# The result is recorded, so the operation is complete. Delete the token
# only now: if the process dies first, rerunning with the saved token
# returns this same stored response instead of creating a second project.
# If the request was rejected, delete the file before retrying with a
# corrected payload - a corrected request is a new action.
os.remove(TOKEN_FILE)
Connect remembers a token's result for 24 hours — even when that result was an error. Sending the same token again only replays the remembered result; it never performs the action a second time. So: retrying the same action, reuse the token; doing anything new, use a new one.
Check progress
Use project statistics for progress and assignments for answers
GET /project/{projectId}/statisticsRead pending, in-progress, completed, approved, completion-rate, bounce-rate, and duration metrics.
GET /assignments/{projectId}Retrieve participant IDs, assignment IDs, status, payment, completion, and template input/submission data.
GET /project/{projectId}Read the current status and settings before pausing, resuming, closing, or archiving the project.
Check periodically rather than continuously. Wait longer between checks, stop after a reasonable deadline, and use each response to decide what your system should do next.
Review and payment
Record every approval, rejection, and bonus
Work meets the stated task and should be paid.
API details →Work fails the task. Provide the required rejection category and message.
API details →A rejected assignment should now be approved and the account has sufficient funds.
API details →Reward exceptional effort. Include a unique idempotency token so a retry cannot pay twice.
API details →Large result sets
Retrieve every page of results
When a list is too large for one response, the API returns a nextToken. Include that token in the next request to get the next page. Continue until the response no longer includes a token.
next_token = None
while True:
params = {"size": 100}
if next_token:
params["nextToken"] = next_token
response = api.get(
"https://connect-api.cloudresearch.com/api/v1/project",
params=params,
)
response.raise_for_status()
page = response.json()
process(page["projects"])
next_token = page.get("nextToken")
if not next_token:
break
Before you go live
Make the automation easy to monitor and troubleshoot
Save related IDs together. Store your item or batch ID with its Connect project, assignment, participant, and task-row IDs.
Save idempotency tokens. If your process restarts, it must use the original token to retry the same request safely.
Log trace IDs. Capture X-TRACE-ID whenever a response fails or looks unexpected.
Check status before changing it. Read the current project status before setting it to Live, Paused, Closed, or Archived.
Limit progress checks. Wait longer between checks, set a deadline, and alert your team when a project stalls or closes unexpectedly.
Track task versions. Record which dataset, label choices, instructions, and template produced each result.
Apply these patterns to your workflow
Use the same lifecycle for many kinds of data collection
The same project lifecycle supports research studies, structured review, business data collection, AI training, and model evaluation. Open the AI data guide to see one complete image-labeling example.