Creating users
When upserting targets via the Targets: Bulk Upsert endpoint, you can optionally create a volunteer user account for each target. This is useful for integrations which need to provision user access alongside importing member data.
User creation is best-effort — if user creation fails for a given record, the target data is still imported successfully. See Limitations for details on when user creation can fail silently.
Parameters
The following parameters can be included alongside the standard target fields in each record:
| Parameter | Type | Default | Description |
|---|---|---|---|
create_user | Boolean | false | Whether to create a volunteer user for this target. Accepts true, "y", or "Y" to enable. |
create_user_role_slugs | String | Space-separated role slugs to assign to the user (e.g. "volunteer", "co-ordinator volunteer"). The special value "_remove" removes all roles from the user. | |
create_user_organisation_type | String | The organisation type to create the user's role against. Must match the external_type of an organisation attached to the target. |
An email address is required on the target for user creation to proceed. If the email is blank, user creation is silently skipped.
Example request
curl https://subdomain.yourmovement.org/api/targets/bulk_upsert \
-XPOST \
-H 'Authorization: Bearer API_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"records": [
{
"external_id": "MEM001",
"first_name": "Jane",
"last_name": "Smith",
"email": "[email protected]",
"phone_number": "+441234567890",
"create_user": true,
"create_user_role_slugs": "volunteer",
"create_user_organisation_type": "branch"
}
]}'How user creation works
When create_user is set to true (or "y"), the system follows this process:
1. Organisation selection
The system determines which organisation to create the user's role against, using the following priority:
- If
create_user_organisation_typeis provided, it finds an organisation of that type attached to the target. If none is found, user creation is skipped. - Otherwise, if the client has a default
create_user_org_kindconfigured, an organisation of that type is used. - Failing both of the above, the national organisation is used.
2. Matching existing users
Before creating a new user, the system checks for an existing user in this order:
- A user already linked to the target (matching
target_id) - A user with the same email address (who is not linked to any target)
- A user with the same phone number (who is not linked to any target)
If an existing user is found, their details are updated rather than creating a new account.
3. Creating or updating the user
New user: A new user account is created with an auto-generated secure password and the volunteer role on the selected organisation. The user is automatically approved.
Existing user: The user's name, email, phone number, and target link are updated. If the organisation has changed, their existing roles are moved to the new organisation (unless they are currently on the national organisation).
4. Role assignment
If create_user_role_slugs is provided, the specified roles replace any existing roles on the selected organisation:
- Multiple roles can be specified as a space-separated string, e.g.
"co-ordinator volunteer" - The special value
"_remove"removes all roles from the user - If
create_user_role_slugsis not provided, existing roles are left unchanged
Limitations
User creation is best-effort. If it fails, the target record is still created — only the user account is not provisioned. The record may appear in the rejected array in the deferred result, but note that in this case the target data has been imported; only the user creation step failed.
- Email is required. If the target has no email address, user creation is silently skipped with no error.
- Email uniqueness. If a user with the same email already exists and is linked to a different target, user creation will fail. The system only matches unlinked users (those with no target association) when looking for an existing account to update. A user who is already linked to another target will not be matched, and the attempt to create a new user with the same email will be rejected by the uniqueness constraint.
- Phone number uniqueness. Similarly, if a user with the same phone number already exists and is linked to a different target, user creation may fail due to the phone number uniqueness constraint.
- Organisation type must exist. If
create_user_organisation_typeis specified but no organisation of that type is attached to the target, user creation is silently skipped. - Invalid role slugs. If a role slug provided in
create_user_role_slugsdoes not match any configured role, the operation will raise an error for that record.
Reading row-level results
The bulk upsert endpoint processes records asynchronously and returns a deferred_result_id which you can poll to check progress. See the Asynchronous operations guide for full details.
To check the result, poll the deferred results endpoint:
GET /api/deferred_results/{deferred_result_id}
While processing, the response will have "status": "running". Once complete, the response will look like:
{
"status": "ready",
"result": {
"record_count": 3,
"upserted_count": 2,
"rejected": [
{
"external_id": "MEM003",
"first_name": "Bob",
"last_name": "Jones",
"email": "[email protected]",
"create_user": true,
"error": "Validation failed: Email has already been taken"
}
]
}
}The rejected array contains the original record data for any records that encountered an error during processing. Each rejected record includes an error key with a description of what went wrong. For errors raised during processing (such as email uniqueness violations from create_user), this will contain the specific error message. For records that fail validation before processing begins (e.g. missing external_id), the error will be "Validation failed".
For example, if a user with the email [email protected] already exists and is linked to a different target, the error will be:
"error": "Validation failed: Email has already been taken"If the entire job fails unexpectedly, the status will be "failed" with an error key containing a message.
Deferred results are available for 24 hours after creation.
Updated about 1 month ago
