Candidate Progress API
Scope note. This is a Trua Cloud (workforce-screening) API. It is not a Trust Bureau (TTB) API. Within TTB, the term Lifecycle is reserved for trust-token lifecycle (created → active → degraded → stale → expired → revoked). Candidate progress through a workforce-screening wizard is a different concept — see TTB Token API for the token lifecycle.
The Candidate Progress API allows relying parties to monitor candidate verification progress programmatically. Instead of checking the Trua Cloud dashboard manually, your systems can poll this API to determine where a candidate is in the Collect wizard, what steps they have completed, and when status transitions occurred.
The endpoint path remains /api/v1/candidates/:id/lifecycle for backward compatibility with existing integrations — only the user-facing documentation term has been updated.
Authentication
All API requests require a Bearer token. Your organization receives two API keys during onboarding:
| Key Type | Prefix | Purpose |
|---|---|---|
| Test key | sk_test_ |
Returns sandbox fixture responses for development and QA |
| Live key | sk_live_ |
Returns real candidate data in production |
Include the key in the Authorization header of every request:
Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxx
API keys are scoped to your organization. You can only query candidates associated with invitations your organization created. Attempting to access another organization's candidates returns a 404 Not Found response.
Key Security
API keys are hashed with BCrypt on the server — Trua Cloud never stores your key in plaintext. The first 12 characters of the key serve as a lookup prefix; the full key is verified against the stored hash on each request.
If you believe a key has been compromised, contact your Trua Cloud representative to revoke it. Revoked keys are rejected immediately on the next API call. A replacement key can be generated without affecting your other keys.
You can view your masked key prefixes in your site portal under API Keys. The full key value is shown only once at generation time.
Test Mode vs Live Mode
Requests made with a test key (sk_test_) are intercepted by the Trua Cloud sandbox middleware and return fixture responses. No real candidate data is queried. This lets you build and validate your integration before any candidates complete the wizard.
| Candidate ID | Sandbox Response |
|---|---|
| Any valid ID | Success fixture with sample progress data |
404 |
Not-found fixture (404 response) |
500 |
Error fixture (500 response) |
Use the Test Harness in your site portal to try sandbox responses interactively.
Requests made with a live key (sk_live_) pass through to the real API and return actual candidate data.
Endpoint
GET /api/v1/candidates/:id/lifecycle
The :id parameter is the candidate's invitation identifier (e.g., INV-12345). This identifier is returned when you create an invitation through the dashboard or API.
Request Example
curl -X GET https://cloud.trua.com/api/v1/candidates/INV-12345/lifecycle \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxx" \
-H "Accept: application/json"
Response Schema
A successful request returns a 200 OK response with the following JSON structure:
{
"candidate_id": "INV-12345",
"email": "candidate@example.com",
"current_status": "in_progress",
"current_step": "employment_history",
"transitions": [
{ "status": "draft", "at": "2026-01-15T10:00:00Z" },
{ "status": "sent", "at": "2026-01-15T10:05:00Z" },
{ "status": "started", "at": "2026-01-16T14:00:00Z" },
{ "status": "in_progress", "at": "2026-01-16T14:02:00Z" }
],
"completion_percentage": 45,
"steps": [
{ "id": "personal_info", "status": "complete" },
{ "id": "consents", "status": "complete" },
{ "id": "employment_history", "status": "in_progress" },
{ "id": "education", "status": "pending" },
{ "id": "professional_licenses", "status": "pending" },
{ "id": "review", "status": "pending" },
{ "id": "signature", "status": "pending" }
]
}
Field Reference
| Field | Type | Description |
|---|---|---|
candidate_id |
string | The invitation identifier for this candidate. |
email |
string | The candidate's email address. |
current_status |
string | The candidate's overall progress status (see Status Values below). |
current_step |
string | The wizard step the candidate is currently on, or null if the wizard has not been started or is already complete. |
transitions |
array | An ordered list of status transitions, each with a status and an ISO 8601 at timestamp. |
completion_percentage |
integer | An estimate of wizard progress from 0 to 100, based on completed steps. |
steps |
array | A list of all wizard steps with their individual status (pending, in_progress, or complete). |
Status Values
The current_status field and the entries in the transitions array use the following values:
| Status | Description |
|---|---|
draft |
The invitation has been created but not yet sent to the candidate. |
sent |
The invitation email has been delivered to the candidate. |
started |
The candidate has opened the invitation link and entered their access code. |
in_progress |
The candidate has begun filling out wizard steps. |
submitted |
The candidate has completed the wizard and signed the attestation. Data is being processed. |
complete |
The verification data package is finalized and available for retrieval. |
expired |
The invitation expired before the candidate completed the wizard (90-day limit). |
Status transitions are strictly ordered. A candidate moves forward through these statuses and does not revert to a previous status.
Error Responses
401 Unauthorized
Returned when the Authorization header is missing, malformed, or contains an invalid, revoked, or disabled API key.
{
"error": "unauthorized",
"message": "Invalid or missing API key."
}
404 Not Found
Returned when the candidate ID does not exist or does not belong to your organization.
{
"error": "not_found",
"message": "Candidate not found."
}
429 Too Many Requests
Returned when your organization has exceeded the rate limit (see Rate Limiting below).
{
"error": "rate_limited",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"retry_after": 60
}
Rate Limiting
API requests are rate-limited to 100 requests per minute per API key. The current limit and remaining quota are included in response headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1737984000
If you exceed the limit, you will receive a 429 Too Many Requests response. Wait for the number of seconds indicated in the retry_after field before retrying.
For monitoring multiple candidates, we recommend polling at an interval of no more than once per minute per candidate. If you are tracking a large volume of candidates, consider batching your polling or spacing requests to stay within the rate limit.
Webhook Notifications
Trua Cloud delivers real-time webhook notifications when a candidate's progress status changes. If you provided a callback_url when creating the invitation, events are delivered there automatically. Otherwise, set the TRUA_FACADE_CALLBACK_URL environment variable as a fallback.
Event Types
| Event | Trigger |
|---|---|
invitation.sent |
Invitation email delivered to candidate |
invitation.expired |
Invitation expired (14 days without candidate starting) |
submission.completed |
Candidate submitted the form |
submission.updated |
Submission data modified |
verification.completed |
Background verification finished |
verification.status_changed |
Verification status transitioned |
data.retention_expiring |
Data approaching 90-day retention limit (sent at 60 days) |
data.terminated |
Data purged per retention policy (90 days) |
Delivery
- Webhooks are delivered via HTTP POST to your
callback_url - Your endpoint must return
2xxwithin 30 seconds (10-second connection timeout) - Failed deliveries are retried up to 5 times with exponential backoff
- Each request includes
X-Bureau-Signatureheader for verification
For full webhook payload formats, signature verification examples, and delivery details, see the Collection Customer API webhook reference.
Integration Notes
- All timestamps are in UTC and formatted as ISO 8601.
- The
completion_percentageis an approximation. It is calculated based on the number of completed steps relative to the total required steps for the candidate's verification package. - Step IDs in the
stepsarray correspond to the wizard steps described in the Collect Workflow Guide. - If an invitation expires, the progress record remains queryable for 90 days after expiration. After that, the record is purged and requests will return
404. - API key usage is tracked: each successful authentication updates the key's
last_used_attimestamp, visible to admins in the site management dashboard.