Help

Provision user accounts with SCIM

tutorial
Last updated:

User Provisioning is the process in Identity and Access Management which ensures that user accounts are created, changed, disabled and deleted in an automated fashion, dependent on staff turnover and changes within organization, which helps reducing the cost of identity management for IT teams and large organizations.

Zapier offers user provisioning support with the SCIM API, a protocol used by identity providers to manage people across a multitude of tools. It is also possible to use our SCIM API for managing the members of your team programmatically.

What is SCIM?

SCIM is an open standard supported by various SaaS applications and identity providers, such as Okta and OneLogin. It runs on top of HTTP as REST API, in which the proper use of the verbs is paramount.

The base URL of the API is https://zapier.com/scim/v2, with all SCIM methods branching off from this base URL. In order to use the API, you will need to generate an API token. In order to do that, you need to go to the Provision tab in Zapier, enable user provisioning for your account and generate the corresponding API token. If you ever lose the token or you have reasons to believe that it is compromised, you can use the same page to regenerate it, marking the previous one as unavailable.

The API token must be included in an Authorization header with a type of Bearer as in Authorization: Bearer . Here is an example of a potential request to list all users belonging to your account:

GET https://zapier.com/scim/v2/Users
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>

{
    "itemsPerPage": 50,
    "startIndex": 1,
    "totalResults": 7,
    "Resources": [
        {
            "userName": "user@zapier.com",
            "meta": {
                "resourceType": "User",
                "lastModified": "2014-10-02T15:04:52+00:00",
                "location": "https://zapier.com/scim/v2/Users/1",
                "created": "2014-10-02T10:04:43+00:00"
            },
            "displayName": "Zaply Zap",
            "name": {
                "givenName": "Zaply",
                "formatted": "Zaply Zap",
                "familyName": "Zap"
            },
            "groups": [],
            "active": true,
            "id": 1,
            "emails": [
                {
                    "primary": true,
                    "value": "user@zap.com"
                }
            ],
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User"
            ]
        },
   ....
   ]
}

Zapier supports the version 2.0 of the SCIM protocol.

Features

We support the following provisioning features.

1. Push New Users
New users created through your identity provider will also be created in Zapier.

2. Push Profile Updates
Updates made to the user's profile through your identity provider will be pushed to Zapier.

3. Push User Deactivation
Deactivating the user or deleting the user will deactivate the user in Zapier.

4. Reactivate User
Reactivated users also get reactivated in Zapier.

Prerequisites

Single Sign-On with SAML is only available to customers on our Company plan. Once you are on our Company plan, head over to the User Provisioning tab to start configuring user provisioning.


1. SCIM API endpoints

The SCIM API is a RESTful API with a predefined set of capabilities and a standardized output. There are two main resources that are usually exposed with a SCIM API, Users and Groups. The first one maps to team account members, while the second one maps to Teams workspaces. You can provision Teams workspaces membership as well as Teams provisioning and depo

You can use these APIs to add or remove members from your team account accordingly. If you use an identity provider for automatic user provisioning, the identity provider will take care of most of these details.

  • GET /ServiceProviderConfigs

Return the configuration details for our API, including which operations are supported.

  • GET /Schemas/Users

Returns configuration details for how users are formatted.

  • GET /Schemas/Groups

Returns configuration details for how team workspaces are formatted.

  • GET /Users

Returns a paginated list of users, fifty users per page by default. You can control the start and the number of users with the startIndex and count parameters.

This endpoint also has support for sorting, with the parameters sortBy, which requires a field to sort against, and sortOrder which can be either ascending or descending.

In case you want to filter out the returned attributes, you can use the attributes parameter, which should be a list of comma separated field names to return from the API.

Lastly, this endpoint also supports filtering the users with the filter parameter. Check the filter section for finding out what part of the SCIM filter DSL we support.

GET /scim/v2/Users?startIndex=1&count=50
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • POST /Users

Create a new member in your team account. This API requires at least userName to be passed, which needs to be an email address. If you use an Identity Provider for automatic user provisioning, make sure to configure it for sending the userName as an email address. In case there is already a user with the same email address, a 409 status code will be returned.

POST /scim/v2/Users
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    'schemas': ['urn:ietf:params:scim:schemas:core:2.0:User'],
    'userName': 'user@domain.com',
    'externalId': '1234',
    'name': {
        'formatted': 'User Name',
        'familyName': 'Name',
        'givenName': 'User',
    }
}

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": 1,
    "userName": "user@domain.com",
    "name": {
        "formatted": "User Name",
        "familyName": "Name",
        "givenName": "User",
    }
    "displayName": "User Name",
    "emails": [
        {
            "value": "user@domain.com",
            "primary": true
        },
    ],
    "timezone": "America/Chicago",
    "active":true
}
  • POST /Users/.search

You can use this endpoint in the same way as using the filter parameter with the GET /Users API, but with this one you submit the filter in the body of your request.

POST /scim/v2/Users
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    'filter': 'userName eq "user@username.com"',
    'attributes': ['id', 'userName'],
}
  • GET /Users/{id}

Retrieves a single member.

GET /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • PATCH /Users/{id}

Updates an existing team member. Attributes that are not defined remain unchanged. You can use this endpoint to re-active a previously suspended account, by sending active set to true in your payload.

This API endpoint is a bit special, as it requires a particular format when sending the request. The spec mentions in great detail what the structure of a PATCH request should be. Right now we only support the Add and Replace operations.

Deactivate a user:

PATCH /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{"op": "Replace", "value": {"active": false}}]
}

Change the email address of a user:

PATCH /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
    {
        "op": "replace",
        "value": {
            "emails": [
                {
                    "value": "user@domain.com",
                    "type": "work",
                    "primary": true
                }
            ],
        },
    }
}
  • PUT /Users/{id}

Updates a single team member, overwriting all values even an attribute is empty or not provided.
You can use this endpoint to re-active a previously suspended account, by sending active set to true in your payload.

PUT /scim/v2/Users/id
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "userName": "user@domain.com",
    "externalId": "2341",
    "name": {
        "formatted": "Name User",
        "familyName": "User",
        "givenName": "Name",
    }
}

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": 1,
    "userName": "user@domain.com",
    "name": {
        "formatted": "Name User",
        "familyName": "User",
        "givenName": "Name",
    }
    "displayName": "User Name",
    "emails": [
        {
            "value": "user@domain.com",
            "primary": true
        },
    ],
    "timezone": "America/Chicago",
    "active":true
}
  • DELETE /Users/{id}

Deprovision a team member. We do not delete users with this endpoint, instead we mark them and their team membership as inactive. As such, they are not able to log in in Zapier until they are activated again. Deactivated users also will be hidden from future requests, but you can use PATCH and PUT to reprovision these users again.

DELETE /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • GET /Groups

Returns a paginated list of teams, fifty groups per page by default. This endpoint supports
the same parameters for sorting, ordering, selection of returned attributes and partially
for filtering.

GET /scim/v2/Groups?startIndex=1&count=50
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "Resources": [
        "id": 1,
        "displayName": "Engineering",
        "members": [
            {"display": "a_member@domain.com", "value": 1},
            {"display": "another_member@domain.com", "value": 2},
        ],
        "id": 2,
        "displayName": "Marketing",
        "members": [
            {"display": "a_member@domain.com", "value": 1},
        ]
    ]
}
  • POST /Groups

Create a new team in your company account. This API requires at least displayName to be passed. In case there is a team with the same name, a 409 will be returned.

POST /scim/v2/Groups
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "displayName": "Engineering",
    "members": [
        {"display": "a_member@domain.com", "value": 1},
        {"display": "another_member@domain.com", "value": 2},
    ]
}

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "id": 1,
    "displayName": "Engineering",
    "members": [
        {"display": "a_member@domain.com", "value": 1},
        {"display": "another_member@domain.com", "value": 2},
    ]
}
  • POST /Groups/.search

You can use this endpoint in the same way as using the filter parameter with the GET /Groups API, but with this one you submit the filter in the body of your request.

POST /scim/v2/Groups
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "filter": 'displayName eq "Engineering"',
    "attributes": ["members"],
}
  • GET /Groups/{id}

Retrieves a single team.

GET /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • PATCH /Groups/{id}

Updates an existing team. Attributes that are not defined remain unchanged.

This API endpoint is a bit special, as it requires a particular format when sending the request. The spec mentions in great detail what the structure of a PATCH request should be.

Change a team's name:

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {"op": "Replace", "value": {"displayName": "Marketing"}}]
}

Add one or multiple team members to the given team. $ref is optional, but if given, it should be
the full URL to the resource represented by the SCIM service provider API.

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "Add",
            "path": "members",
            "value": [
                {
                    'display': 'John Smith',
                    '$ref': 'https://zapier.com/v2/Users/1',
                    'value': 1,
                },
                {
                    'display': 'John Doe',
                    '$ref': 'https://zapier.com/v2/Users/2',
                    'value': 2,
                }
            ]
        }
    ]
}

Replace all members in a team with the given list:

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "Replace",
            "path": "members",
            "value": [
                {
                    'display': 'John Smith',
                    '$ref': 'https://zapier.com/v2/Users/1',
                    'value': 1,
                },
                {
                    'display': 'John Doe',
                    '$ref': 'https://zapier.com/v2/Users/2',
                    'value': 2,
                }
            ]
        }
    ]
}

Remove one or multiple members from a team:

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "Remove",
            "path": "members[value eq 'johndoe@domain.com']",
        },
        {
            "op": "Remove",
            "path": "members[value eq 'johnsmith@domain.com']",
        }
    ]
}
  • PUT /Groups/{id}

Updates a single team, overwriting its fields entirely.

 :::json
PUT /scim/v2/Groups/1
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "displayName": "Engineering",
    "members": [
        {"display": "a_member@domain.com", "value": 1},
        {"display": "another_member@domain.com", "value": 2},
    ]
}
  • DELETE /Groups/{id}

Deprovision a team and remove all of its memberships.

  • GET /Me

This API represents the owner of the account. The API will return a redirect to the corresponding user endpoint.

A quick word on timezones

When supplied, timezones in provisioning requests are expected to be in the IANA format some examples of which are shown below:

'America/Los_Angeles'
'Europe/Amsterdam'
'UTC'

2. SCIM filter

The /Users and /Groups endpoint have support for filtering the resources by using the SCIM filter DSL specified in the SCIM protocol spec. The following rules apply to the filter parameter:

  • It must contain a valid boolean operator
  • It needs to respect the format attribute name, followed by attribute operator, followed by attribute value. As an example, filter=userName eq “user@zapier.com” is a valid filter.
  • Multiple expressions can be combined using two logical operators.
  • Expressions can be grouped together using "()"
  • String literals must be valid JSON strings.

Zapier supports the following operators:

eq  equal
co  contains
sw  starts with
gt  greater than
ge  greater than or equal
lt  less than
le  less than or equal
and logical And
or  logical Or

Here are some examples of filters you can use:

  • userName eq “user@example.com”
  • id eq 1234
  • id eq 1234 or userName co “@example.com”
  • userName sw user
  • displayName eq "Engineering"

3. Configuration steps

Configure your Provisioning settings for Zapier:

  • Head over to the User Provisioning tab in the app settings.
  • Enable User Provisioning by hitting the Enable button
  • Once User Provisioning is enabled, a new authentication token will be generated. Use it to configure your identity provider to send the requests at the base SCIM URL, which is https://zapier.com/scim/v2.
  • If your identity provider requires a SCIM template, use the following JSON template:

    :::json
    {
    "schemas": [
    "urn:scim:schemas:core:1.0"
    ],
    "userName": "{$parameters.scimusername}",
    "active": "{$user.active}",
    "name": {
    "givenName": "{$user.firstname}",
    "familyName": "{$user.lastname}",
    "formatted": "{$user.display_name}"
    }
    }

If everything went fine, you should see a screen similar to the following:
Enabled provisioning


4. Integrate with OneLogin

To integrate OneLogin SCIM and Zapier:

  • Add a new company app that uses SCIM, most likely SCIM Provisioner with SAML (SCIM v2). Alternatively, you can use the official OneLogin Zapier app for configuring both SAML and SCIM.
  • Once added, go to the Configuration tab and set the proper values.
  • For the SCIM Base URL field, use https://zapier.com/scim/v2/
  • For the SCIM JSON Template field, use the following value:

    :::javascript
    {
    "schemas": [
    "urn:scim:schemas:core:1.0"
    ],
    "userName": "{$parameters.scimusername}",
    "active": "{$user.active}",
    "name": {
    "givenName": "{$user.firstname}",
    "familyName": "{$user.lastname}",
    "formatted": "{$user.display_name}"
    }
    }

  • For the SCIM Bearer Token field, use the token generated by you in the provisioning tab from Zapier.

  • Go to the Parameters tab and set the SCIM Username to be the username from OneLogin. We expect that the username is an email address. Yours should look like in this example:

OneLogin parameters

Once that is ready, go to the provisioning tab to enable it. You can opt to approve all the provisioning steps that OneLogin does, this might be useful to you depending or not if you want to test the user provisioning before enabling it for your entire account.

OneLogin provisioning


5. Integrate with Okta

To integrate Okta SCIM and Zapier:

  • Add a new company app for SCIM. You can use our early access Okta app, which offers both SAML and SCIM support.
  • Once added, enable provisioning and go to the provisioning tab.
  • Enable the corresponding capabilities, such as Create Users and Update User Attributes
  • In the attribute mappings section, make sure that the attribute mapping that Okta uses looks like the one from the screenshot:

Okta provisioning


6. Integrate with AzureAD

Learn how to set up SCIM for AzureA.

It's important to configure to set the proper attribute mapping for AzureAD. By default, it uses their internal ID for the userPrincipalName, but we need to receive an email address as the identifier of a user. Your attribute mapping should look like in the following screenshot:

AzureAD


7. Troubleshooting tips and limitations

  • The team owner cannot be de-provisioned. If you want to do that, you have to first transfer your Zapier account to someone else.
  • Users cannot be permanently deleted from Zapier, they will be deactivated instead. A deactivated user can be reactivated.
  • Users cannot change their details on accounts that have user provisioning enabled.
  • Users cannot be created with domains that are not verified by the team. Domains can be verified under the Domains section in Settings.
  • The SCIM API is rate limited. If your requests are being limited, a 429 response will be returned.
  • The SCIM API does not support the full filter DSL as specified in the SCIM spec. We do support most of the common filters though, check the filter section on what exactly is supported.
  • The username must be the same as the email address in Zapier. For certain identity providers, these values can be configured separately, but if these values are not equal, we will raise an error during provisioning. Also, the username cannot be updated independently of the email, you need to update both in a single request, otherwise an error will be returned.
  • Because of SAML JIT, changing the username of a user in the identity provider could result in a new user being provisioned, as we use the email address to create or update users. If possible, configure your identity provider to send with the SAML attributes the internalId parameter, set to the internal ID of your identity provider. This should look along the lines of the following screenshot, depending on your identity provider:

internal_id

If sending an internalId is not possible, changing the username of a user will result in a new user being provisioned during SAML SSO JIT.

  • If no explicit timezone was defined for users, we either use UTC or Central Time depending on the context. A user that has a blank timezone in Zapier will also have a blank timezone in the identity provider. If it is possible for your identity provider, mark the timezone field as required, but do note that you will not be able to bulk import users that have no timezone set in Zapier.

Was this doc helpful?

Need More Help?

Zapier Support

Contact our world class support team and we’ll be happy to help you get up and running!
Contact Us

Hire an Expert

We have a directory of professionals across the globe who are ready to help.
Find a Zapier Expert