Overview
The Dualog User API facilitates adding and extraction of user data from the Dualog system using the SCIM schema. This guide covers authentication steps and request procedures for accessing user data.
Swagger documentation is also available here: https://apps.dualog.com/api/cd-customer-scim-public-api/index.html
Authentication
To authenticate, obtain an OAuth 2.0 token via client credentials and use this token to access the API endpoints.
Obtaining a Client ID and Secret
To interact with the Dualog User API, you will need a client ID and client secret.
Creation Process
An API client needs to be created in the Dualog Portal
- Go to the Organization page in the Dualog portal to create an API Client.
- You can generate Client IDs and secrets for users or organizations.
- User: Grants access to all organizations your user has.
- Organization: Restricts access to that organization only.
Select the appropriate scopes during creation. Use crew_import for full read/write access, or crew_read for read-only access to the Dualog User API.
User vs Organisation
Client IDs and secrets can be generated either for individual users or for organizations. When you create an identity client for a user, the access scope includes all organizations the user has access to. If created for an organization, the access scope is limited to only that organization. This access is re-evaluated with each API request, ensuring current permissions are respected.
Client Scope
During the creation process, you will select the access scopes for the client. Scopes define the API endpoints your client can access, organizing them into logical units for easier management.
Available scopes:
- crew_import: Grants full read and write access to User and Group endpoints.
- crew_read: Grants read-only access to User and Group endpoints.
Obtaining an OAuth 2.0 Token
1. Client Credentials Request:
Request an OAuth 2.0 token from the Dualog Identity Server:
POST https://apps.dualog.com/auth/connect/tokenEnsure requests use HTTPS to secure data in transit.
2. Authorization Header:
Encode ClientId and ClientSecret as ClientId:ClientSecret in Base64 and include it in the header:
Authorization: Basic <EncodedString>
3. Request Body:
Use application/x-www-form-urlencoded content type with the following payload:
grant_type=client_credentials&scope=crew_import4. Response:
A successful response includes an access_token, its validity (expires_in), token_type, and scope:
{
"access_token": "<access_token>",
"expires_in": 86400,
"token_type": "Bearer",
"scope": "crew_import"
}This indicates the token's 24-hour validity and applicable scopes. Handle this token securely.
Using the Access Token
Include the access_token in the authorization header of your API requests:
Authorization: Bearer <access_token>SCIM Schema for User
The API returns user data in JSON format, adhering to the SCIM 2.0 ListResponse schema. Key components:
- schemas: Array containing "urn:ietf:params:scim:api:messages:2.0:ListResponse".
- totalResults: Total number of results from the query.
- startIndex: 1-based index for the first result.
- itemsPerPage: Number of results per page.
- Resources: Array of user objects. Each user object includes id, userName, name (with familyName and givenName), displayName, active status, emails, and custom attributes under the urn:ietf:params:scim:schemas:extension:seafarer:2.0:User:crew schema.
Supported Fields
The Dualog User API supports a variety of fields within the SCIM schema to ensure comprehensive management of user data. Here's a breakdown of the primary fields you can expect within user objects and their significance:
Core User Fields
- id: A unique identifier for the user. This is used to reference the user across the API.
- externalId: An optional identifier from an external system, used to map users across systems.
- userName: The user's login name (email address) or identifier, typically used for authentication purposes.
-
name: An object that includes the user's full name details:
- familyName: The user's last name or surname.
- givenName: The user's first name or given name.
- displayName: The full name of the user, suitable for display purposes. It can be the same as givenName + familyName or a different preferred name.
- active: A boolean indicating whether the user's account is active or not. Useful for managing user access.
- emails: An array of objects detailing the user's email addresses. Each object can specify the email type (work, home) and whether it's the primary email.
- groups: An array of objects detailing the user groups assigned to the user. Each object can specify the user group identifier defined in the system.
- password: An optional field used to set the initial password for the created user.
Custom Fields (Crew Extension)
- urn:ietf:params:scim:schemas:extension:seafarer:2.0:User:crew: This is a custom extension schema to accommodate specific fields for the maritime industry, including:
- rank: The user's rank.
- department: The user's department.
- shipName: The name of the ship the user is currently assigned to.
- shipImo: The International Maritime Organization number for the ship, providing a unique identifier.
- contractStartDate: A date (in yyyy-MM-dd format) when the user started working on board.
- contractEndDate: A date (in yyyy-MM-dd format) when the user finishes work on board.
- forceChangePassword: A boolean indicating whether the user must change their password on next login.
-
userFields: A list of custom properties set for the user. The list can be expanded in the future and includes:
- businessUnit: The business unit the user is assigned to.
Metadata Fields
-
meta: Contains metadata about the user object, such as:
- resourceType: Type of the SCIM resource (e.g., "User").
- created: The datetime when the user object was created.
- lastModified: The last time the user object was updated.
- location: The URL where the user object can be accessed.
User Endpoints
Fetching Users
HTTP Method: GET Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users
Query Parameters
- startIndex: 1-based index of the first result to return.
- count: Number of results per page.
- filter: SCIM filter expression for server-side filtering. Supported fields: userName, externalId, meta.created, meta.lastModified, contractStartDate, contractEndDate.
Filter examples:
userName eq "jdoe@company.com"
externalId eq "EXT-001"
meta.created gt "2024-01-01T00:00:00Z"
contractEndDate lt "2025-06-01"Pagination
To manage large datasets, the API supports pagination:
Specify startIndex and count to paginate responses:
GET https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users?startIndex=1&count=10The response includes totalResults, startIndex, itemsPerPage, and the actual Resources. To retrieve all users, adjust startIndex in subsequent requests based on count and totalResults until all data is fetched.
Response Body
{
"schemas": ["urn:ietf:params:scim:api:messages:2.0:ListResponse"],
"totalResults": 3,
"startIndex": 1,
"itemsPerPage": 3,
"Resources": [
{
"id": "87234",
"userName": "example_user@acme-tankers.com",
"displayName": "Example User",
"active": true
}
]
}
Status Codes
| Status Code | Description |
| 200 OK | Users successfully retrieved. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Fetching a User
HTTP Method: GET Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users/{userId}
Response Body
{
"id": "87234",
"externalId": "EXT-001",
"userName": "jdoe@company.com",
"name": {
"familyName": "Doe",
"givenName": "John"
},
"displayName": "John Doe",
"active": true,
"emails": [
{
"value": "jdoe@company.com",
"display": "Work Email",
"type": "work",
"primary": true
},
{
"value": "john.doe@example.com",
"display": "Personal Email",
"type": "home",
"primary": false
}
],
"groups": [
{
"value": "6480"
}
],
"meta": {
"resourceType": "User",
"created": "2021-01-15T12:34:56Z",
"lastModified": "2021-06-01T09:30:00Z",
"location": "https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users/87234"
},
"urn:ietf:params:scim:schemas:extension:seafarer:2.0:User:crew": {
"rank": "A/B",
"department": "Deck",
"shipName": "Voyager",
"shipImo": "1234567",
"contractStartDate": "2021-01-17",
"contractEndDate": "2022-01-16",
"forceChangePassword": false,
"userFields": [
{
"key": "businessUnit",
"value": "Company Unit"
}
]
}
}
- Added "externalId": "EXT-001"
- Added "forceChangePassword": false
- Changed meta.location URL from /api/v2/ to /api/scim/v2/
-
Changed extension key from Crew to full SCIM URI urn:ietf:params:scim:schemas:extension:seafarer:2.0:User:crew
Status Codes
| Status Code | Description |
| 200 OK | User successfully retrieved. |
| 401 Unauthorized | Authentication required. |
| 404 Not Found | User not found. |
| 500 Internal Server Error | Server encountered an error. |
Creating a User
HTTP Method: POST Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users
Content-Type: application/json
Required fields: The following fields are required in the request body: active, emails, groups, name, and the urn:ietf:params:scim:schemas:extension:seafarer:2.0:User:crew object (which must include at least an empty userFields array). All other fields are optional.
Note:
- The userName field must be an email address with a valid email domain. This email will be created for the user.
- The externalId optional field can be used to associate the user with an identifier from an external system. [NEW]
- The shipImo optional field must match the IMO number of a ship specified in the system.
- The contractStartDate field is only required if the shipImo field is present in the request. It must be specified in yyyy-MM-dd format and must not be older than the current date.
- The contractEndDate optional field's date (in yyyy-MM-dd format) must not be before the contractStartDate field's date. If not provided, the end date will be set one year after the start date.
- The password optional field must match password policy specified in the system.
- The groups optional field values must be valid user group identifiers specified in the system.
- The forceChangePassword optional boolean field can be set to require the user to change their password on first login.
Request Body
{
"userName": "jdoe@company.com",
"externalId": "EXT-001",
"name": {
"familyName": "Doe",
"givenName": "John"
},
"displayName": "John Doe",
"active": true,
"password": "Zaq!123Wsx",
"emails": [
{
"value": "john.doe@example.com",
"type": "home"
}
],
"groups": [
{
"value": "6480"
}
],
"urn:ietf:params:scim:schemas:extension:seafarer:2.0:User:crew": {
"rank": "Captain",
"department": "Command",
"shipImo": "7654321",
"contractStartDate": "2023-01-01",
"contractEndDate": "2023-12-31",
"forceChangePassword": true,
"userFields": [
{
"key": "businessUnit",
"value": "Company Unit"
}
]
}
}- Added "externalId": "EXT-001"
- Added "forceChangePassword": true
- Removed "schemas" array (response-only, should not be in request)
Response Body
Returns the created user object (same structure as the GET single user response above), with system-generated fields such as id, meta, and schemas populated.
Note: The schemas array is returned in the response but should not be included in the request body.
Status Codes
| Status Code | Description |
| 201 Created | User successfully created. |
| 400 Bad Request | Invalid input data. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Updating a User
HTTP Method: PUT Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users/{userId}
Content-Type: application/json
Important: PUT replaces the entire user resource. Any fields omitted from the request body will be cleared. Always include all required fields and any optional fields you wish to retain.
Request Body: Same as the request body for creating a user. Response Body: Same as the response body for creating a user.
Status Codes
| Status Code | Description |
| 200 OK | User successfully updated. |
| 400 Bad Request | Invalid input data. |
| 401 Unauthorized | Authentication required. |
| 404 Not Found | User not found. |
| 500 Internal Server Error | Server encountered an error. |
Deleting a User
HTTP Method: DELETE Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Users/{userId}
Status Codes
| Status Code | Description |
| 204 No Content | User successfully deleted. |
| 401 Unauthorized | Authentication required. |
| 404 Not Found | User not found. |
| 500 Internal Server Error | Server encountered an error. |
Group Endpoints
Listing Groups
HTTP Method: GET Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Groups
Query Parameters
- startIndex: 1-based index of the first result to return.
- count: Number of results per page.
Status Codes
| Status Code | Description |
| 200 OK | Groups successfully retrieved. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Getting a Group
HTTP Method: GET Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Groups/{groupId}
Status Codes
| Status Code | Description |
| 200 OK | Group successfully retrieved. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Creating a Group
HTTP Method: POST Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Groups
Content-Type: application/json
The request body must include displayName (required) and may include members (an array of member objects with value and type fields).
Status Codes
| Status Code | Description |
| 201 Created | Group successfully created. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Updating a Group
HTTP Method: PUT Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Groups/{groupId}
Content-Type: application/json
Request and response body: Same structure as creating a group.
Status Codes
| Status Code | Description |
| 200 OK | Group successfully updated. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Deleting a Group
HTTP Method: DELETE Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/scim/v2/Groups/{groupId}
Status Codes
| Status Code | Description |
| 204 No Content | Group successfully deleted. |
| 401 Unauthorized | Authentication required. |
| 500 Internal Server Error | Server encountered an error. |
Managing User Group Membership
You can add or remove a single group from a user without affecting other group assignments. These endpoints operate on the legacy path.
Add Group to User
HTTP Method: PUT Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/v2/Users/{userId}/Groups/{groupId}
Remove Group from User
HTTP Method: DELETE Endpoint: https://apps.dualog.com/api/cd-customer-scim-public-api/api/v2/Users/{userId}/Groups/{groupId}
Status Codes
| Status Code | Description |
| 204 No Content | Group membership successfully updated. |
| 401 Unauthorized | Authentication required. |
| 404 Not Found | User or group not found. |
| 500 Internal Server Error | Server encountered an error. |
Discovery & Metadata Endpoints
- Discovery: GET /api/scim/v2 — Returns all available SCIM endpoints.
- Resource Types: GET /api/scim/v2/ResourceTypes — Returns all available resource types.
- Schemas: GET /api/scim/v2/Schemas — Lists all available resource schemas.
- Service Provider Config: GET /api/scim/v2/ServiceProviderConfig — Returns the service provider configuration.
Error Handling
When interacting with the Dualog User SCIM API, it's important to handle errors gracefully. The API uses standard HTTP status codes to indicate the success or failure of requests. Below are common error responses you might encounter:
- 400 Bad Request: Your request is invalid.
- 401 Unauthorized: Authentication failed. This usually means your access token is missing, invalid, or expired. Ensure you have obtained a valid token and included it in your request header.
- 403 Forbidden: You're authenticated but not authorized to perform the requested operation. Verify that your account has the necessary permissions.
- 404 Not Found: The specified resource could not be found. This could mean a wrong URL or the resource does not exist.
- 500 Internal Server Error: An unexpected error occurred on the server side. If this persists, contact Dualog support.
For each error response, the API may also provide a JSON body with more details, including a specific error message and potentially an error code. Here's an example of an error response body:
{
"type": "https://httpstatuses.com/400",
"title": "BadRequest",
"status": 400,
"detail": "Bad request",
"correlationId": "91dab160-dc7d-49c0-b412-fe28720154f0"
}Handling these errors involves checking the HTTP status code and any accompanying error message or code in the response body. Use this information to debug issues or display meaningful error messages to users. Additionally, implement retry logic for transient errors (like 500) and refresh tokens when encountering 401 errors with expired tokens.
Comments
Article is closed for comments.