Create a user import job.
curl --request POST \ --url https://auth.example.com/api/admin/jobs/users/import \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "file_key": "imports/default/018f3f7c/users.csv", "size_bytes": 4096, "content_type": "text/csv", "checksum_sha256": "9d6f965ac832e40a5c8a5d7aa7a4b1e0e67f...", "options": { "skip_header": true, "on_duplicate": "skip", "validate_only": false } }'Registration state is read-only: CSV registration_state and user_type=anonymous are rejected. Updating an existing guest with user_type=end_user preserves guest registration; promotion requires the account upgrade flow. Queues a users/import job for an already uploaded CSV artifact. The handler verifies tenant ownership, content type, size, checksum, and import options before creating the pending job. CSV headers and cell values are normalized before schema validation. Group conditions evaluate only validated, persisted attributes after account publication, never raw CSV columns. New accounts use the durable account-directory creation workflow. A row awaiting publication remains uncounted in processed/succeeded totals and resumes with the same job/row identity; progress logs expose directory_pending. Existing users are updated on their verified account storage route. A replay of this job’s own account creation precedes duplicate-email handling.
Optional columns ial (IAL1, IAL2 or IAL3) and ial_verified_at (a date, or a date-time with a time zone; the time of the import when omitted) assert the identity assurance of the person. A new account is created with it as import evidence of the job, in place of the tenant’s default IAL (assurance.default_ial, recorded as tenant-policy evidence when a row gives none). For an existing account (on_duplicate=update), a row with an ial replaces what earlier imports asserted, and a row without one keeps it; evidence of other sources is never touched. A claim is the level with its verification time (ial_verified_at, or the time the job was created when the row gives none), so the same level without a date in a later import is a new verification, while the same job processed again records nothing new. A CSV import is an administrator’s action: it is not held to the ceiling on what SCIM tokens may assert (assurance.scim_max_ial). ial_verified_at without ial, an unknown ial, a time in the future and a date that does not exist (February 30, month 13) fail the row. The columns are read as assurance only where the tenant has no custom attribute named ial or ial_verified_at (such names cannot be given to a custom attribute, nor an inactive one with such a name made active): while it has, a row with the column fails (also when only validated; checked for each such row) until the attribute is renamed or the column removed. Import evidence is identified by its content (person, ial, ial_verified_at; the time of the job when the row gives none), from any job: identical content never re-activates evidence that was revoked, whoever revoked it, so a row processed again after a failure records nothing new. Evidence of an existing account is written only after its row was updated, so a row that fails changes none; a row whose evidence step failed after the update is reported as assurance_update_failed (retryable) and is imported again. When the tenant default cannot be read, a row without ial fails with default_ial_unavailable (retryable) and creates nothing; import it again. When a new account was written but its evidence could not be recorded, the row is not counted: the job tries it again (up to five times), which finds the row’s creation operation and completes it, recording the evidence once; after that the row fails as assurance_initial_failed (retryable) and its creation stays unfinished.
Authorizations
Section titled “Authorizations ”Request Body required
Section titled “Request Body required ”object
object
Example
{ "file_key": "imports/default/018f3f7c/users.csv", "size_bytes": 4096, "content_type": "text/csv", "checksum_sha256": "9d6f965ac832e40a5c8a5d7aa7a4b1e0e67f...", "options": { "skip_header": true, "on_duplicate": "skip", "validate_only": false }}Responses
Section titled “ Responses ”User import job accepted response.
object
Example
{ "status": "pending"}Error response.
object
Example generated
{ "error": "example", "message": "example", "error_description": "example"}Error response.
object
Example generated
{ "error": "example", "message": "example", "error_description": "example"}Error response.
object
Example generated
{ "error": "example", "message": "example", "error_description": "example"}Error response.
object
Example generated
{ "error": "example", "message": "example", "error_description": "example"}Error response.
object
Example generated
{ "error": "example", "message": "example", "error_description": "example"}Error response.
object
Example generated
{ "error": "example", "message": "example", "error_description": "example"}