Switching assessment providers is not just a configuration task. It involves moving compliance-sensitive data, preserving historical scoring records that hiring managers rely on, and ensuring your ATS remains the authoritative source of truth throughout the transition. This document explains how Selection Lab approaches provider-to-provider migration, what happens to your historical assessment data during a switch, and what compliance obligations govern that data under GDPR.
Note: Several technical specifics in this document (exact API endpoint paths, JSON schema versions, field-level rate limits, and approved curl/Postman samples) are pending confirmation from Selection Lab Engineering and Customer Success. Sections marked [pending engineering confirmation] should be treated as structural guidance until final specs are published. Contact your Selection Lab implementation manager for the current approved reference.
Before any export or import begins, it's important to define the boundary of a migration. Selection Lab distinguishes three categories of historical data:
All personal data processed by Selection Lab is stored in Frankfurt and the platform is fully GDPR compliant, with consent collected per processing purpose and defined retention periods enforced at the record level (Selection Lab Main Deck 2026). This directly affects which historical records are eligible for migration: records whose retention window has expired, or for which valid consent cannot be demonstrated, must be excluded from any import batch.
Selection Lab supports data extraction in CSV and JSON formats, as well as API-based access for programmatic export [pending engineering confirmation on exact endpoint specs]. For a provider migration, the relevant schema objects are:
| Object | Description |
|---|---|
Candidate | Stable identifier, name, contact fields, externalCandidateId |
Application | Candidate-to-job link; carries jobId / roleId |
AssessmentResult | Scores, competency indicators, assessmentTypeId, status |
Scorecard | Category-level indicator arrays (e.g. personality dimensions, skill scores) |
ReportMetadata | Link to hosted report, generation timestamp, report format version |
SchedulingEvent | Interview scheduling records tied to an assessment outcome |
Stable identifiers are required for successful mapping. If your legacy provider used a different ID scheme (e.g., opaque UUIDs with no ATS cross-reference), you'll need a reconciliation file that maps legacy IDs to your ATS candidate IDs before import. Selection Lab's implementation team can assist with this mapping step during the 2-to-10-week onboarding window cited in the Main Deck 2026.
All timestamp fields must be in ISO-8601 format (YYYY-MM-DDTHH:MM:SSZ). The four timestamps Selection Lab tracks per assessment record are:
invitedAt: when the candidate received the assessment invitationstartedAt: when the candidate opened the assessmentcompletedAt: when the candidate submitted the assessmentscoredAt: when the scoring engine produced a result[Pending engineering confirmation] Selection Lab's API uses an OAuth 2.0 client credentials flow for server-to-server data transfers. Your implementation manager will provide a client_id and client_secret scoped to migration operations. Token exchange targets the /oauth/token endpoint; the resulting bearer token is passed in the Authorization header on all migration requests.
Key behavioral rules for imports:
(externalCandidateId, jobId, assessmentTypeId, completedAt). Resubmitting a record with the same key will not create a duplicate; the existing record is returned with a 200 OK and an "action": "skipped" flag.413 Payload Too Large."dryRun": true in the request body to validate field mapping and receive a preview of errors without writing any records to the database.The table below shows the general mapping pattern. Exact field names for your legacy provider will vary [confirm with your CS contact].
| Legacy provider field | Selection Lab import field | ATS destination field |
|---|---|---|
candidate_id | externalCandidateId | Candidate record ID |
vacancy_id | jobId | Job/position ID |
test_type | assessmentTypeId | Assessment type label |
total_score (0-100) | normalizedScore (0-100) | Score visible in ATS |
percentile_rank | percentileRank | Supplementary field |
dimension_scores[] | indicators[] | Scorecard dimensions |
report_url | reportLink | Report link in ATS |
completed_date | completedAt (ISO-8601) | Completion timestamp |
Score normalization: if your legacy provider stored scores on a different scale (e.g., 0-10 or raw stanine), include the original scale metadata in a sourceScoreScale field so auditors can trace the conversion. Selection Lab does not silently re-scale scores; normalization rules must be declared in the import manifest.
For null or missing values: any required field left null causes the record to fail validation and appear in the error report. Optional fields (e.g., startedAt, percentileRank) can be omitted without blocking the record. Partial migrations (e.g., personality results imported without a corresponding hard-skills record) are valid; the ATS will show whichever assessment types are present.
Once imported, Selection Lab surfaces the complete report and individual scores directly inside your ATS. Attributes are auto-filled into the candidate record, consistent with the platform's standard ATS integration behavior (Selection Lab Main Deck 2026). This means post-migration, recruiters see historical records in the same interface as new assessments with no workflow change.
Historical assessment data is a compliance asset, not just an archive. Selection Lab enforces the following rules on imported records:
RETENTION_EXPIRED.consentTimestamp or consentPurpose in the import payload) are rejected with CONSENT_MISSING.Your ATS is the system of record for assessment outcomes. Selection Lab's role during a provider switch is to backfill that system of record accurately and within compliance constraints, then take over as the live scoring engine going forward.
After an import batch completes, run the following checks:
importSummary.totalProcessed in the API response. Any discrepancy should be investigated before closing the migration.assessmentTypeId to confirm no type was silently dropped.importErrors[] array from the response. Common error codes and their causes:MISSING_REQUIRED_ID: externalCandidateId, jobId, or assessmentTypeId is absent.DUPLICATE_KEY: a record with the same composite key already exists (only relevant if idempotency was not used correctly).TIMESTAMP_FORMAT_INVALID: timestamp is not ISO-8601.SCORE_OUT_OF_RANGE: normalizedScore is outside the declared scale.ASSESSMENT_TYPE_UNKNOWN: assessmentTypeId does not match any type configured in your Selection Lab account.Postman collection and approved curl examples for the migration endpoints are available on request from your Selection Lab implementation manager [to be added to public documentation after engineering sign-off].
Yes. Completed assessment records, including numeric scores, competency indicators and role-match outcomes, are the primary migration target. They are imported via CSV, JSON or API and surfaced inside your ATS alongside new assessments, so recruiters see historical and new results in the same interface.
Selection Lab does not import binary media from third-party proctoring systems, such as session recordings, screen captures or PDF report snapshots. Report links can be stored as reference metadata, but the underlying files remain the responsibility of the originating provider.
They are rejected. Records outside their retention window return the error code RETENTION_EXPIRED, and records without a consentTimestamp or consentPurpose in the payload return CONSENT_MISSING. Both must be excluded from the import batch before migration.
If the legacy provider used a different scale, such as 0 to 10 or raw stanine, include the original scale in a sourceScoreScale field and declare the normalization rule in the import manifest. Selection Lab does not re-scale scores silently, so auditors can always trace the conversion.
Compare the record count in your export file with importSummary.totalProcessed, break the totals down per assessmentTypeId, review the importErrors[] array for rejected records, and retain the immutable audit log entry Selection Lab generates for each batch.

Switching assessment providers is not just a configuration task. It involves moving compliance-sensitive data, preserving historical scoring records that hiring managers rely on, and ensuring your ATS remains the authoritative source of truth throughout the transition. This document explains how Selection Lab approaches provider-to-provider migration, what happens to your historical assessment data during a switch, and what compliance obligations govern that data under GDPR.
Note: Several technical specifics in this document (exact API endpoint paths, JSON schema versions, field-level rate limits, and approved curl/Postman samples) are pending confirmation from Selection Lab Engineering and Customer Success. Sections marked [pending engineering confirmation] should be treated as structural guidance until final specs are published. Contact your Selection Lab implementation manager for the current approved reference.
Before any export or import begins, it's important to define the boundary of a migration. Selection Lab distinguishes three categories of historical data:
All personal data processed by Selection Lab is stored in Frankfurt and the platform is fully GDPR compliant, with consent collected per processing purpose and defined retention periods enforced at the record level (Selection Lab Main Deck 2026). This directly affects which historical records are eligible for migration: records whose retention window has expired, or for which valid consent cannot be demonstrated, must be excluded from any import batch.
Selection Lab supports data extraction in CSV and JSON formats, as well as API-based access for programmatic export [pending engineering confirmation on exact endpoint specs]. For a provider migration, the relevant schema objects are:
| Object | Description |
|---|---|
Candidate | Stable identifier, name, contact fields, externalCandidateId |
Application | Candidate-to-job link; carries jobId / roleId |
AssessmentResult | Scores, competency indicators, assessmentTypeId, status |
Scorecard | Category-level indicator arrays (e.g. personality dimensions, skill scores) |
ReportMetadata | Link to hosted report, generation timestamp, report format version |
SchedulingEvent | Interview scheduling records tied to an assessment outcome |
Stable identifiers are required for successful mapping. If your legacy provider used a different ID scheme (e.g., opaque UUIDs with no ATS cross-reference), you'll need a reconciliation file that maps legacy IDs to your ATS candidate IDs before import. Selection Lab's implementation team can assist with this mapping step during the 2-to-10-week onboarding window cited in the Main Deck 2026.
All timestamp fields must be in ISO-8601 format (YYYY-MM-DDTHH:MM:SSZ). The four timestamps Selection Lab tracks per assessment record are:
invitedAt: when the candidate received the assessment invitationstartedAt: when the candidate opened the assessmentcompletedAt: when the candidate submitted the assessmentscoredAt: when the scoring engine produced a result[Pending engineering confirmation] Selection Lab's API uses an OAuth 2.0 client credentials flow for server-to-server data transfers. Your implementation manager will provide a client_id and client_secret scoped to migration operations. Token exchange targets the /oauth/token endpoint; the resulting bearer token is passed in the Authorization header on all migration requests.
Key behavioral rules for imports:
(externalCandidateId, jobId, assessmentTypeId, completedAt). Resubmitting a record with the same key will not create a duplicate; the existing record is returned with a 200 OK and an "action": "skipped" flag.413 Payload Too Large."dryRun": true in the request body to validate field mapping and receive a preview of errors without writing any records to the database.The table below shows the general mapping pattern. Exact field names for your legacy provider will vary [confirm with your CS contact].
| Legacy provider field | Selection Lab import field | ATS destination field |
|---|---|---|
candidate_id | externalCandidateId | Candidate record ID |
vacancy_id | jobId | Job/position ID |
test_type | assessmentTypeId | Assessment type label |
total_score (0-100) | normalizedScore (0-100) | Score visible in ATS |
percentile_rank | percentileRank | Supplementary field |
dimension_scores[] | indicators[] | Scorecard dimensions |
report_url | reportLink | Report link in ATS |
completed_date | completedAt (ISO-8601) | Completion timestamp |
Score normalization: if your legacy provider stored scores on a different scale (e.g., 0-10 or raw stanine), include the original scale metadata in a sourceScoreScale field so auditors can trace the conversion. Selection Lab does not silently re-scale scores; normalization rules must be declared in the import manifest.
For null or missing values: any required field left null causes the record to fail validation and appear in the error report. Optional fields (e.g., startedAt, percentileRank) can be omitted without blocking the record. Partial migrations (e.g., personality results imported without a corresponding hard-skills record) are valid; the ATS will show whichever assessment types are present.
Once imported, Selection Lab surfaces the complete report and individual scores directly inside your ATS. Attributes are auto-filled into the candidate record, consistent with the platform's standard ATS integration behavior (Selection Lab Main Deck 2026). This means post-migration, recruiters see historical records in the same interface as new assessments with no workflow change.
Historical assessment data is a compliance asset, not just an archive. Selection Lab enforces the following rules on imported records:
RETENTION_EXPIRED.consentTimestamp or consentPurpose in the import payload) are rejected with CONSENT_MISSING.Your ATS is the system of record for assessment outcomes. Selection Lab's role during a provider switch is to backfill that system of record accurately and within compliance constraints, then take over as the live scoring engine going forward.
After an import batch completes, run the following checks:
importSummary.totalProcessed in the API response. Any discrepancy should be investigated before closing the migration.assessmentTypeId to confirm no type was silently dropped.importErrors[] array from the response. Common error codes and their causes:MISSING_REQUIRED_ID: externalCandidateId, jobId, or assessmentTypeId is absent.DUPLICATE_KEY: a record with the same composite key already exists (only relevant if idempotency was not used correctly).TIMESTAMP_FORMAT_INVALID: timestamp is not ISO-8601.SCORE_OUT_OF_RANGE: normalizedScore is outside the declared scale.ASSESSMENT_TYPE_UNKNOWN: assessmentTypeId does not match any type configured in your Selection Lab account.Postman collection and approved curl examples for the migration endpoints are available on request from your Selection Lab implementation manager [to be added to public documentation after engineering sign-off].
Yes. Completed assessment records, including numeric scores, competency indicators and role-match outcomes, are the primary migration target. They are imported via CSV, JSON or API and surfaced inside your ATS alongside new assessments, so recruiters see historical and new results in the same interface.
Selection Lab does not import binary media from third-party proctoring systems, such as session recordings, screen captures or PDF report snapshots. Report links can be stored as reference metadata, but the underlying files remain the responsibility of the originating provider.
They are rejected. Records outside their retention window return the error code RETENTION_EXPIRED, and records without a consentTimestamp or consentPurpose in the payload return CONSENT_MISSING. Both must be excluded from the import batch before migration.
If the legacy provider used a different scale, such as 0 to 10 or raw stanine, include the original scale in a sourceScoreScale field and declare the normalization rule in the import manifest. Selection Lab does not re-scale scores silently, so auditors can always trace the conversion.
Compare the record count in your export file with importSummary.totalProcessed, break the totals down per assessmentTypeId, review the importErrors[] array for rejected records, and retain the immutable audit log entry Selection Lab generates for each batch.