---
title: "Import users from a collection"
method: POST
path: "/apps/{id}/users/import"
tags: ["Apps"]
---

# Import users from a collection

`POST /apps/{id}/users/import`

## Request

- Base URL: `https://api.hypamoon.com/api/v1`
- URL: `https://api.hypamoon.com/api/v1/apps/{id}/users/import`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://app.hypamoon.com/oauth/authorize`, token URL `https://api.hypamoon.com/oauth/token`, scopes: `sites:write`)

Makes the people in a collection (default wp_users, from the Hypamoon Connect plugin for WordPress) users of the app, with role_map from WordPress roles to app roles. No passwords: people sign in with a link or code by email. send_email false (the default) adds them silently; true emails each new person an invitation, within the invitation limits (20 per hour and 100 per day per app; the rest is reported as remaining with retry_after). Idempotent on the WordPress id and the email address: people who can already sign in are left as they are. The app user id is written back into each document (hypamoon_app_users). dry_run shows the plan without changing anything.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `collection` string: The collection with the people, default wp_users (from the Hypamoon Connect plugin). Each document needs email; name comes from display_name, name or first_name and last_name; roles from roles (a list) or role.
  - `role_map` object: WordPress role to app role, like { "administrator": "admin", "opdrachtgever": "opdrachtgever", "kandidaat": "kandidaat" }. A person gets the app role of the first of their roles that is in the map. Without role_map, a WordPress role with the same name as an app role is used.
  - `default_role` string, nullable: The app role for people whose roles are not in role_map. Leave it out (or null) to skip them; without role_map the app's default_role is used.
  - `send_email` boolean: false (the default): add them silently, no email; they sign in later with a link or code they request on the site. true: email each new person an invitation (counts toward the app's invitation limits and the email budget).
  - `invite_existing` boolean: Only with send_email true: also email people who were added earlier (for example silently) and never signed in. Default false, so running the import again sends nothing twice.
  - `dry_run` boolean: true: change nothing, only show who would be added with which role.

## Response `200`

What happened per person.

- object
  - `app_id` string, uuid, required
  - `collection` string, required
  - `dry_run` boolean, required
  - `send_email` boolean, required
  - `summary` object, required: created: added now (invited: of those, emailed). existing: could already sign in (matched on WordPress id or email; their role is not changed). remaining: not done yet because of a limit; call again.
    - `found` integer, required
    - `created` integer, required
    - `invited` integer, required
    - `existing` integer, required
    - `skipped` integer, required
    - `remaining` integer, required
  - `users` object[], required: Per person what happened, in the order of the collection.
    - `wp_id` union, required
      - number
      - string
    - `user_id` string, uuid, nullable, required: The app user id (sub in x-hypamoon-user): use it as the owner in the app's tables.
    - `email` string, required: Masked, like s***@example.com.
    - `role` string, nullable, required
    - `status` 'created' | 'invited' | 'existing' | 'skipped' | 'would_create' | 'remaining', required
    - `reason` string
  - `retry_after` integer: Seconds to wait before the remaining invitations can go out.
  - `next_step` string, required

## Other responses

- `400`: Bad Request: invalid_json.
- `401`: Unauthorized: unauthorized, missing_api_key, invalid_api_key, api_key_revoked, project_deleted.
- `403`: Forbidden: project_not_enabled, key_mode_mismatch, missing_scope, verification_required.
- `404`: Not Found: not_found.
- `409`: Conflict: conflict.
- `422`: Unprocessable Content: validation_failed.
- `429`: Too Many Requests: rate_limited.
- `500`: Internal Server Error: internal_error.
- `503`: Service Unavailable: service_unavailable.

---

[API](https://skmtc.dev/hypamoon/apis/hypamoon-api.md) · [All operations](https://skmtc.dev/hypamoon/apis/hypamoon-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hypamoon/apis/hypamoon-api/revisions/9f0b90004c06?raw)
