The Generic REST Directory Connector lets OneLogin import users from any external system that exposes a REST API returning JSON, without a purpose-built connector. You describe the API in a JSON template: how to authenticate, which requests to make, and how to read users from the responses. The directory service runs that template to import users into OneLogin.
Examples
See the examples section for step-by-step walkthroughs of configuring the connector for specific source systems.
How it works
Each Generic REST directory holds two JSON templates and a set of secrets:
| Item | Purpose |
|---|---|
| Authorization template | Declares the authentication methods used to call the remote API, including OAuth 2.0 flows (authorization code and client credentials). Multiple authorizations can be defined for a single directory. |
| Communication template | Declares the HTTP requests used for each import action and how to interpret the responses. |
| Tokens | Secret values, such as API keys, that templates reference instead of embedding. Tokens and OAuth access and refresh tokens are stored encrypted. |
OAuth access tokens are refreshed automatically. If a response matches an oauth_refresh status code defined in the template, the connector refreshes the token and retries the request.
Import actions
The import section of the communication template defines one request per action:
| Action | Required | Description |
|---|---|---|
users | Yes | Returns the users to import. |
users_count | Yes | Returns the total number of users. |
user_ids | Yes | Returns the unique identifiers of the users. |
fields | Yes | Returns the user fields the remote system supports. |
optional_fields | No | Returns additional fields that can optionally be mapped. |
An optional export section can define requests for creating and updating users and for searching by email in the remote system.
User attributes
Imported users must provide external_id, firstname and lastname. At least one of email or username is also needed. The following attributes are optional: phone, company, title, department, notes and distinguished_name. A status attribute can also be supplied to update the OneLogin user status (active, unactivated or suspended).
Attribute mapping and custom fields
Attributes from the source system can also be mapped to any custom fields created in your OneLogin tenant to extend the user schema, not just the standard OneLogin attributes. You control how attributes flow from the source system to OneLogin in the attribute mapping section of the connector. This section becomes available after the connector has successfully connected to the source system.
Request configuration
Each request can specify the following properties.
| Property | Description |
|---|---|
base_url, path | The target of the request. These can be set once at the import level and inherited by individual actions. |
full_url | An absolute URL that takes precedence over base_url and path. Used for next-page links. |
method | The HTTP method. |
headers, isolated_headers | Request headers. |
parameters, body | Query string parameters and request body. |
skip_empty_body_properties | Omit body properties that resolve to empty values. |
page_increase | Pagination by incrementing a parameter or body value. |
replay | Repeat the request until a condition is met. See Pagination. |
responses | How to validate, extract and filter the response. |
A request can also be an ordered list of requests, where later requests use the output of earlier ones through previous_response.
Template variables
Templates use {$variable} placeholders, resolved when each request runs. Values can be read with dotted paths or bracketed keys, for example {$tokens.api_key}. The following root variables are available:
| Variable | Contents |
|---|---|
tokens | The directory’s stored token values. |
oauth.access_tokens | The current OAuth access tokens, keyed by authorization name. |
responses | Responses from earlier requests in a chained request. |
pagination | The current pagination state. |
user | The user being processed, for export requests. |
user_status | The OneLogin user status values active, unactivated and suspended. |
Response handling
The responses block of a request controls how the result is read:
extractselects the data to return. See How extraction works.validatechecks that the response contains what is expected.filtersexcludes records from the result.- Per-status handlers, keyed by HTTP status code, apply different
extract,validateandfilterssettings depending on the response code. oauth_refreshlists the status codes that trigger an OAuth token refresh.
How extraction works
After each request, the connector parses the JSON response and applies the extract configuration to turn it into the data the import needs, such as a list of users with named attributes. The names you give each extracted property are the source attribute names you later map to OneLogin attributes in the connector’s attribute mapping.
Extraction types
Each extracted property is an object containing one or more extraction types. At least one is required.
| Type | Description |
|---|---|
*by_path | Reads a value from the response using a dot-separated path. |
*raw | Uses a fixed string, which can contain template variables. |
*constant | Uses a fixed value, typically as a fallback. |
#map | Optional. Translates the extracted value using a lookup table. |
When more than one type is given, the first non-empty value wins, in the order *by_path, *raw, *constant.
Paths
A *by_path value must start with body (the JSON response body) or headers (the response headers). The rest of the path walks the JSON structure:
| Path element | Meaning |
|---|---|
name | The property with that name. |
0, 1, … | The item at that position in an array. |
* | Every item in an array. |
*f | Flattens nested arrays into one array. |
*length | The number of items in an array. |
For example, body.*.custom_attributes.hr_firstname reads custom_attributes.hr_firstname from every item in a response whose body is an array.
Extracting a list of users
To extract many records, wrap the extract configuration in an array. Each extracted property is evaluated across the whole response, and the results are combined by position to build one user per item. A property that returns a single value rather than a list, such as a *raw or *constant value, is applied to every user.
"extract": [
{
"first_name": { "*by_path": "body.*.custom_attributes.hr_firstname" },
"last_name": { "*by_path": "body.*.custom_attributes.hr_lastname" },
"staffid": { "*by_path": "body.*.custom_attributes.hr_staff_id" },
"managerID": { "*by_path": "body.*.custom_attributes.hr_managerID" },
"personal_email": { "*by_path": "body.*.custom_attributes.hr_personal_email" },
"isManager": { "*by_path": "body.*.custom_attributes.hr_isManager" },
"title": { "*by_path": "body.*.custom_attributes.hr_title" },
"id": { "*by_path": "body.*.id" },
"status": {
"*by_path": "body.*.custom_attributes.hr_user_status",
"#map": {
"active": "{$user_status.active}",
"disabled": "{$user_status.suspended}",
"terminated": "{$user_status.suspended}"
}
},
"hr_driven_identity": { "*raw": "TRUE" },
"department": {
"*by_path": "body.*.custom_attributes.hr_department",
"*constant": "missing"
}
}
]This example shows the supported patterns:
- Custom and nested attributes.
*by_pathreaches into nested objects such ascustom_attributes, so provider-specific fields likehr_staff_idcan be imported alongside standard ones such asid. Extracted properties can be mapped to custom fields in OneLogin. See Attribute mapping and custom fields. - Value translation with
#map. Thestatusproperty converts the source system’s values into OneLogin user statuses. Values with no entry in the map pass through unchanged, and numeric strings in the result are converted to numbers. - Fixed values with
*raw.hr_driven_identityis set toTRUEfor every imported user. - Fallback values with
*constant. If a user has nohr_departmentvalue,departmentis set tomissinginstead of being left empty.
Limits
Extract configurations can be nested up to 50 levels deep. Extract configurations that don’t specify at least one extraction type, or that use a *by_path value without a body or headers prefix, are rejected when the template is validated. Required user attributes that extraction doesn’t provide cause the import to fail with an invalid data error.
Pagination
Two pagination styles are supported. They cannot be combined on a single request.
page_increaseincrements a query parameter or body value on each call, for APIs that use page numbers or offsets.replayrepeats the request usingwhileoruntil(exactly one) to decide when to stop. Combined withfull_url, this follows cursor and next-link style pagination, such as the@odata.nextLinkused by Microsoft Graph and Entra ID.
For next-link pagination, the connector only follows full_url values that use http or https and match the origin (scheme, host and port) of the configured base_url, so credentials are never sent to another host. Redirects are not followed. Replay stops with an error after 10,000 iterations rather than importing truncated data. replay is not supported inside a chained request.
Import behavior
| Setting | Value |
|---|---|
| Import strategy | Bulk |
| Page size | 20 |
| Maximum users per import | 11,000 |
| Deprovisioning | Not performed |
| Group import | Not supported |
Imports run in the background and can be started manually or on a schedule. See Scheduled imports.
Scheduled imports
The connector can import users automatically on a schedule. When adding the connector to your tenant, set the Automatic import CRON definition setting to a standard cron expression that defines how often and at what time the import runs. Leave it blank to turn automatic import off. The schedule can be changed or cleared later by editing the connector.
For example:
| Cron expression | Runs |
|---|---|
0 * * * * | Every hour, on the hour |
*/30 * * * * | Every 30 minutes |
0 2 * * * | Every day at 02:00 |
0 6 * * 1-5 | At 06:00, Monday to Friday |
The schedule is validated when you save it:
- It must be a valid cron expression, with a precision of one minute at most. Second-level schedules are rejected.
- The interval between runs must be at least 5 minutes.
A scheduled run works the same way as a manual import. It does not run when:
- The connector is disabled. Disabling it removes the schedule, and the schedule is registered again when the connector is re-enabled.
- No schedule is set.
- A previous import is still in progress. The run is skipped, and the next scheduled time starts a new import.
Choose an interval longer than a typical import duration, so that runs don’t regularly overlap and get skipped.
Security
- Token values and OAuth tokens are encrypted at rest and are excluded from logs.
- Plain
httpis only followed for pagination URLs on the same origin as the configuredbase_url. Usehttpsendpoints for production integrations.
Related
Have a Question?
Found a problem or a bug? Submit a support ticket.
Looking for walkthroughs or how-to guides? Check out our Knowledge Base.
Have a product idea or request? Share it in our Ideas Portal.