One document matched: draft-ietf-scim-api-03.xml
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='http://xml.resource.org/authoring/rfc2629.xslt' ?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="std" docName="draft-ietf-scim-api-03" ipr="trust200902">
<front>
<title abbrev="draft-scim-api-03">System for Cross-Domain Identity
Management:Protocol</title>
<author fullname="Kelly Grizzle" initials="K.G." surname="Grizzle">
<organization abbrev="SailPoint">SailPoint</organization>
<address>
<email>kelly.grizzle@sailpoint.com</email>
</address>
</author>
<author fullname="Phil Hunt" initials="P." role="editor" surname="Hunt">
<organization abbrev="Oracle">Oracle Corporation</organization>
<address>
<email>phil.hunt@yahoo.com</email>
</address>
</author>
<author fullname="Morteza Ansari" initials="M.A." surname="Ansari">
<organization abbrev="Cisco">Cisco</organization>
<address>
<email>morteza.ansari@cisco.com</email>
</address>
</author>
<author fullname="Erik Wahlström" initials="E.W." surname="Wahlström">
<organization abbrev="Technology Nexus">Technology Nexus</organization>
<address>
<email>erik.wahlstrom@nexussafe.com</email>
</address>
</author>
<author fullname="Chuck Mortimore" initials="C." surname="Mortimore">
<organization abbrev="Salesforce">Salesforce.com</organization>
<address>
<email>cmortimore@salesforce.com</email>
</address>
</author>
<date day="12" month="February" year="2014"/>
<keyword>SCIM</keyword>
<abstract>
<t>The System for Cross-Domain Identity Management (SCIM) specification
is designed to make managing user identity in cloud based applications
and services easier. The specification suite seeks to build upon
experience with existing schemas and deployments, placing specific
emphasis on simplicity of development and integration, while applying
existing authentication, authorization, and privacy models. It's intent
is to reduce the cost and complexity of user management operations by
providing a common user schema and extension model, as well as binding
documents to provide patterns for exchanging this schema using standard
protocols. In essence, make it fast, cheap, and easy to move users in
to, out of, and around the cloud.</t>
</abstract>
</front>
<middle>
<section anchor="intro" title="Introduction and Overview" toc="default">
<t>The SCIM Protocol is an application-level, REST protocol for
provisioning and managing identity data on the web. The protocol
supports creation, modification, retrieval, and discovery of core
identity resources; i.e., Users and Groups, as well as custom resource
extensions.</t>
<section title="Intended Audience" toc="default">
<t>This document is intended as a guide to SCIM API usage for both
identity service providers and clients.</t>
</section>
<section anchor="notat" title="Notational Conventions" toc="default">
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119]. These
keywords are capitalized when used to unambiguously specify
requirements of the protocol or application features and behavior that
affect the interoperability and security of implementations. When
these words are not capitalized, they are meant in their
natural-language sense.</t>
<t>For purposes of readability examples are not URL encoded.
Implementers MUST percent encode URLs as described in <xref
target="RFC3896">Section 2.1 </xref>.</t>
</section>
<section anchor="defs" title="Definitions" toc="default">
<t><list style="hanging">
<t hangText="Base URL:">The SCIM REST API is always relative to a
Base URL. The Base URL MUST NOT contain a query string as clients
may append additional path information and query parameters as
part of forming the request. Example:
https://example.com/scim/v2/</t>
</list></t>
</section>
</section>
<section anchor="aa" title="Authentication and Authorization"
toc="default">
<t>The SCIM protocol does not define a scheme for authentication and
authorization therefore implementers are free to choose mechanisms
appropriate to their use cases. The choice of authentication mechanism
will impact interoperability. It is RECOMMENDED that clients be
implemented in such a way that new authentication schemes can be
deployed. Implementers SHOULD support existing
authentication/authorization schemes. In particular, OAuth2<xref
target="RFC6750"/> is RECOMMENDED. Appropriate security considerations
of the selected authentication and authorization schemes SHOULD be
taken. Because this protocol uses HTTP response status codes as the
primary means of reporting the result of a request, servers are advised
to respond to unauthorized or unauthenticated requests using the 401
response code in accordance with section 10.4.2 of <xref
target="RFC2616">Section 10.4.2 </xref>.</t>
<t>All examples assume OAuth2 bearer token <xref target="RFC6750"/>;
e.g.,</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646 HTTP/1.1
Host: example.com
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>The context of the request (i.e. the user for whom data is being
requested) MUST be inferred by service providers.</t>
</section>
<section anchor="api" title="API">
<t>The SCIM protocol specifies well known endpoints and HTTP methods for
managing resources defined in the core schema; i.e., <spanx
style="verb">User</spanx> and <spanx style="verb">Group</spanx>
resources correspond to <spanx style="verb">/Users</spanx> and <spanx
style="verb">/Groups</spanx> respectively. Service providers that
support extended resources SHOULD define resource endpoints using the
established convention; pluralize the resource name defined in the
extended schema by appending an 's'. Given there are cases where
resource pluralization is ambiguous; e.g., a resource named <spanx
style="verb">Person</spanx> is legitimately <spanx style="verb">Persons</spanx>
and <spanx style="verb">People</spanx> clients SHOULD discover resource
endpoints via the <spanx style="verb">/ResourceTypes</spanx> endpoint
.</t>
<t><list style="hanging">
<t hangText="GET">Retrieves a complete or partial resource.</t>
<t hangText="POST">Create new resource, perform an extended Search,
or bulk modify resources.</t>
<t hangText="PUT">Modifies a resource with a complete, client
specified resource (replace).</t>
<t hangText="PATCH">Modifies a resource with a set of client
specified changes (partial update).</t>
<t hangText="DELETE">Deletes a resource.</t>
</list></t>
<texttable anchor="endpoint-summary" title="Defined endpoints">
<ttcol align="left">Resource</ttcol>
<ttcol align="left">Endpoint</ttcol>
<ttcol align="left">Operations</ttcol>
<ttcol align="left">Description</ttcol>
<c>User</c>
<c>/Users</c>
<c><xref format="default" target="get-resource">GET</xref>, <xref
format="default" target="create-resource">POST</xref>, <xref
format="default" target="edit-resource-with-put">PUT</xref>, <xref
format="default" target="edit-resource-with-patch">PATCH</xref>, <xref
format="default" target="delete-resource">DELETE</xref></c>
<c>Retrieve/Add/Modify Users</c>
<c>Group</c>
<c>/Groups</c>
<c><xref format="default" target="get-resource">GET</xref>, <xref
format="default" target="create-resource">POST</xref>, <xref
format="default" target="edit-resource-with-put">PUT</xref>, <xref
format="default" target="edit-resource-with-patch">PATCH</xref>, <xref
format="default" target="delete-resource">DELETE</xref></c>
<c>Retrieve/Add/Modify Groups</c>
<c>Service Provider Configuration</c>
<c>/ServiceProviderConfigs</c>
<c><xref format="default" target="get-resource">GET</xref></c>
<c>Retrieve the service provider's configuration</c>
<c>Resource Type</c>
<c>/ResourceTypes</c>
<c><xref format="default" target="get-resource">GET</xref></c>
<c>Retrieve the supported resource types</c>
<c>Schema</c>
<c>/Schemas</c>
<c><xref format="default" target="get-resource">GET</xref></c>
<c>Retrieve a resource's schema</c>
<c>Bulk</c>
<c>/Bulk</c>
<c><xref format="default" target="bulk-resources">POST</xref></c>
<c>Bulk modify resources</c>
<c>Search</c>
<c>[prefix]/.search</c>
<c><xref format="default" target="query-post">POST</xref></c>
<c>Perform a search at system root or within a resource endpoint for
one or more resource types using POST.</c>
</texttable>
<t>All requests to the service provider are made via <xref
target="RFC2616">Section 9</xref> on a URL derived from the Base URL.
Responses are returned in the body of the HTTP response, formatted as
JSON. Response and error codes SHOULD be transmitted via the HTTP status
code of the response (if possible), and SHOULD also be specified in the
body of the response.</t>
<section anchor="create-resource" title="Creating Resources"
toc="default">
<t>To create new resources, clients send POST requests to the resource
endpoint; i.e., <spanx style="verb">/Users</spanx> or <spanx
style="verb">/Groups</spanx>.</t>
<t>Successful resource creation is indicated with a 201 ("Created")
response code. Upon successful creation, the response body MUST
contain the newly created resource. Since the server is free to alter
and/or ignore POSTed content, returning the full representation can be
useful to the client, enabling it to correlate the client and server
views of the new resource. When a resource is created, its URI must be
returned in the response Location header.</t>
<t>If the service provider determines creation of the requested
resource conflicts with existing resources; e.g., a <spanx
style="verb">User</spanx> resource with a duplicate <spanx
style="verb">userName</spanx>, the service provider MUST return a 409
error and SHOULD indicate the conflicting attribute(s) in the body of
the response.</t>
<t>Below, the client sends a POST request containing a user</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">POST /Users HTTP/1.1
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
}
}
</artwork>
</figure>
<t>The server signals a successful creation with a status code of 201.
The response includes a Location header indicating the User URI, and a
representation of that user in the body of the response.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 201 Created
Content-Type: application/json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"e180ee84f0671b1"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"externalId":"bjensen",
"meta":{
"resourceType":"User",
"created":"2011-08-01T21:32:44.882Z",
"lastModified":"2011-08-01T21:32:44.882Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"e180ee84f0671b1\""
},
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
},
"userName":"bjensen"
}
</artwork>
</figure>
<section anchor="resourceTypes" title="Resource Types">
<t>When adding a resource to a specific endpoint, the meta attribute
<spanx style="verb">resourceType</spanx> SHALL be set by the service
provider to the corresponding resource Type for the endpoint. For
example, <spanx style="verb">/Users</spanx> will set <spanx
style="verb">resourceType</spanx> to <spanx style="verb">User</spanx>,
and <spanx style="verb">/Groups</spanx> will set <spanx
style="verb">resourceType</spanx> to <spanx style="verb">Group</spanx>.</t>
</section>
</section>
<section anchor="get-resources-ops" title="Retrieving Resources"
toc="default">
<t><spanx style="verb">User</spanx> and <spanx style="verb">Group</spanx>
resources are retrieved via opaque, unique URLs or via Query. Service
providers MAY choose to respond with a sub-set of resource attributes,
though MUST minimally return the resource id and meta attributes.</t>
<section anchor="get-resource" title="Retrieving a known Resource"
toc="default">
<t>To retrieve a known resource, clients send GET requests to the
resource endpoint; e.g., <spanx style="verb">/Users/{id}</spanx> or
<spanx style="verb">/Groups/{id}</spanx>.</t>
<t>If the resource exists the server responds with a status code of
200 and includes the result in the body of the response.</t>
<t>The below example retrieves a single User via the <spanx
style="verb">/Users</spanx> endpoint.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">GET /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>The server responds with:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"f250dd84f0671c3"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"externalId":"bjensen",
"meta":{
"resourceType":"User",
"created":"2011-08-01T18:29:49.793Z",
"lastModified":"2011-08-01T18:29:49.793Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"f250dd84f0671c3\""
},
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
},
"userName":"bjensen",
"phoneNumbers":[
{
"value":"555-555-8377",
"type":"work"
}
],
"emails":[
{
"value":"bjensen@example.com",
"type":"work"
}
]
}
</artwork>
</figure>
</section>
<section anchor="query-resources" title="List/Query Resources"
toc="default">
<t>SCIM defines a standard set of operations that can be used to
filter, sort, and paginate response results. The operations are
specified by adding query parameters to the resource's endpoint.
Service providers MAY support additional query parameters not
specified here, and Providers SHOULD ignore any query parameters
they don't recognize.</t>
<t>List and query responses MUST be identified using the following
URI: <spanx style="verb">urn:scim:schemas:core:2.0:ListResponse</spanx>.
The following attributes are defined for list and query
responses:</t>
<t><list style="hanging">
<t hangText="totalResults">The total number of results returned
by the list or query operation. This may not be equal to the
number of elements in the resources attribute of the list
response if <xref format="default"
target="pagination">pagination</xref> is requested.
REQUIRED.</t>
<t hangText="Resources">A multi-valued list of complex objects
containing the requested resources. This may be a subset of the
full set of resources if <xref format="default"
target="pagination">pagination</xref> is requested.
REQUIRED.</t>
<t hangText="startIndex">The 1-based index of the first result
in the current set of list results. REQUIRED if <xref
format="default" target="pagination">pagination</xref> is
requested.</t>
<t hangText="itemsPerPage">The number of resources returned in a
list response page. REQUIRED if <xref format="default"
target="pagination">pagination</xref> is requested.</t>
</list></t>
<t>The below example returns the userName for all Users:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">GET /Users?attributes=userName
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">HTTP/1.1 200 OK
Content-Type: application/json
{
"schemas":["urn:scim:schemas:core:2.0:ListResponse"],
"totalResults":2,
"Resources":[
{
"userName":"bjensen"
},
{
"userName":"jsmith"
}
]
} </artwork>
</figure>
<section anchor="query-endpoints" title="Query Endpoints">
<t>Queries MAY be performed against a SCIM resource object or a
resource type endpoint. For example: <list>
<t><spanx style="verb">/Users/{userid}</spanx></t>
<t><spanx style="verb">/Users</spanx></t>
<t><spanx style="verb">/Groups</spanx></t>
</list></t>
<t>A server MAY support searches against the server root (e.g.
"/"). A search against a server root indicates that ALL resources
within the server SHALL be included subject to filtering. A filter
expression using <spanx style="verb">meta.resourceType</spanx> MAY
be used to restrict results to one or more specific resource types
(e.g. <spanx style="verb">User</spanx>).</t>
<t>When processing search operations across endpoints that include
more than one SCIM resource type (e.g. a search from the server
root endpoint), filters MUST be processed in the same fashion as
outlined in <xref target="filtering"/>. For filtered attributes
that are not part of a particular resource type, the service
provider SHALL treat the attribute as if there is no attribute
value. For example, a presence or equality filter for an undefined
attribute evaluates as FALSE.</t>
</section>
<section anchor="filtering" title="Filtering">
<t>Filtering is OPTIONAL. Clients may request a subset of
resources by specifying the 'filter' URL query parameter
containing a filter expression. When specified only those
resources matching the filter expression SHALL be returned. The
expression language that is used in the filter parameter supports
references to attributes and literals. The literal values can be
strings enclosed in double quotes, numbers, date times enclosed in
double quotes, and Boolean values; i.e., true or false. String
literals MUST be valid <xref target="RFC4627"/>.</t>
<t>The attribute name and attribute operator are case insensitive.
For example, the following two expressions will evaluate to the
same logical value:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
filter=userName Eq "john"
filter=Username eq "john"
</artwork>
</figure>
<t>The filter parameter MUST contain at least one valid Boolean
expression. Each expression MUST contain an attribute name
followed by an attribute operator and optional value. Multiple
expressions MAY be combined using the two logical operators.
Furthermore expressions can be grouped together using "()".</t>
<t>The operators supported in the expression are listed in the
following table.</t>
<texttable align="left" anchor="filter-operator-table"
title="Attribute Operators">
<ttcol align="left">Operator</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Behavior</ttcol>
<c>eq</c>
<c>equal</c>
<c>The attribute and operator values must be identical for a
match.</c>
<c>ne</c>
<c>not equal</c>
<c>The attribute and operator values are not identical.</c>
<c>co</c>
<c>contains</c>
<c>The entire operator value must be a substring of the
attribute value for a match.</c>
<c>sw</c>
<c>starts with</c>
<c>The entire operator value must be a substring of the
attribute value, starting at the beginning of the attribute
value. This criterion is satisfied if the two strings are
identical.</c>
<c>ew</c>
<c>ends with</c>
<c>The entire operator value must be a substring of the
attribute value, matching at the end of the attribute value.
This criterion is satisfied if the two strings are
identical.</c>
<c>pr</c>
<c>present (has value)</c>
<c>If the attribute has a non-empty value, or if it contains a
non-empty node for complex attributes there is a match.</c>
<c>gt</c>
<c>greater than</c>
<c>If the attribute value is greater than operator value, there
is a match. The actual comparison is dependent on the attribute
type. For string attribute types, this is a lexicographical
comparison and for DateTime types, it is a chronological
comparison.</c>
<c>ge</c>
<c>greater than or equal</c>
<c>If the attribute value is greater than or equal to the
operator value, there is a match. The actual comparison is
dependent on the attribute type. For string attribute types,
this is a lexicographical comparison and for DateTime types, it
is a chronological comparison.</c>
<c>lt</c>
<c>less than</c>
<c>If the attribute value is less than operator value, there is
a match. The actual comparison is dependent on the attribute
type. For string attribute types, this is a lexicographical
comparison and for DateTime types, it is a chronological
comparison.</c>
<c>le</c>
<c>less than or equal</c>
<c>If the attribute value is less than or equal to the operator
value, there is a match. The actual comparison is dependent on
the attribute type. For string attribute types, this is a
lexicographical comparison and for DateTime types, it is a
chronological comparison.</c>
</texttable>
<texttable align="left" anchor="logical-operator-table"
title="Logical Operators">
<ttcol align="left">Operator</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Behavior</ttcol>
<c>and</c>
<c>Logical And</c>
<c>The filter is only a match if both expressions evaluate to
true.</c>
<c>or</c>
<c>Logical or</c>
<c>The filter is a match if either expression evaluates to
true.</c>
<c>not</c>
<c>Not function</c>
<c>The filter is a match if the expression evaluates to
false.</c>
</texttable>
<texttable anchor="grouping-operator-table"
title="Grouping Operators">
<ttcol align="left">Operator</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Behavior</ttcol>
<c>()</c>
<c>Precedence grouping</c>
<c>Boolean expressions may be grouped using parentheses to
change the standard order of operations; i.e., evaluate OR
logical operators before logical AND operators.</c>
<c>[]</c>
<c>Complex attribute filter grouping</c>
<c>Service providers MAY support complex filters where
expressions MUST be applied to the same value of a parent
attribute specified immediately before the left square bracket
("["). The expression within square brackets ("[" and "]") MUST
be a valid filter expression based upon sub-attributes of the
parent attribute. Nested expressions MAY be used. See examples
below.</c>
</texttable>
<t>Filters MUST be evaluated using standard order of operations
<xref target="Order-Operations"> </xref>. Attribute operators have
the highest precedence, followed by the grouping operator (i.e,
parentheses), followed by the logical AND operator, followed by
the logical OR operator.</t>
<t>If the specified attribute in a filter expression is a
multi-valued attribute, the resource MUST match if any of the
instances of the given attribute match the specified criterion;
e.g. if a User has multiple emails values, only one has to match
for the entire User to match. For complex attributes, a fully
qualified Sub-Attribute MUST be specified using standard <xref
format="default" target="attribute-notation">attribute
notation</xref>. For example, to filter by userName the parameter
value is userName and to filter by first name, the parameter value
is name.givenName.</t>
<t>Providers MAY support additional filter operations if they
choose. Providers MUST decline to filter results if the specified
filter operation is not recognized and return a HTTP 400 error
with an appropriate human readable response. For example, if a
client specified an unsupported operator named 'regex' the service
provider should specify an error response description identifying
the client error; e.g., 'The operator 'regex' is not
supported.'</t>
<t>String type attributes are case insensitive by default unless
the attribute type is defined as a caseExact string. Attribute
operators 'eq', 'co', and 'sw' MUST perform caseIgnore matching
for all string attributes unless the attribute is defined as
caseExact. By default all string attributes are caseIgnore.</t>
<t>Clients MAY search by schema or schema extensions by using a
filter expression including the "schemas" attribute.</t>
<t>The following are examples of valid filters. Some attributes
(e.g. rooms and rooms.number) are hypothetical extensions and are
not part of SCIM core schema:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">filter=userName eq "bjensen"
filter=name.familyName co "O'Malley"
filter=userName sw "J"
filter=title pr
filter=meta.lastModified gt "2011-05-13T04:42:34Z"
filter=meta.lastModified ge "2011-05-13T04:42:34Z"
filter=meta.lastModified lt "2011-05-13T04:42:34Z"
filter=meta.lastModified le "2011-05-13T04:42:34Z"
filter=title pr and userType eq "Employee"
filter=title pr or userType eq "Intern"
filter=schemas eq "urn:scim:schemas:extension:enterprise:2.0:User"
filter=userType eq "Employee" and (emails co "example.com" or emails
co "example.org")
filter=userType ne "Employee" and not (emails co "example.com" or
emails co "example.org")
filter=userType eq "Employee" and (emails.type eq "work")
filter=userType eq "Employee" and emails[type eq "work" and
value co “@example.com"]
filter=emails[type eq "work" and value co “@example.com"] or ims[type
eq "xmpp" and value co "@foo.com"]
filter=addresses[state eq "CA" and rooms[type eq "bedroom" and
number gt 2]] </artwork>
</figure>
</section>
<section anchor="sorting" title="Sorting">
<t>Sort is OPTIONAL. Sorting allows clients to specify the order
in which resources are returned by specifying a combination of
sortBy and sortOrder URL parameters.</t>
<t><list style="hanging">
<t hangText="sortBy:">The sortBy parameter specifies the
attribute whose value SHALL be used to order the returned
responses. If the sortBy attribute corresponds to a singular
attribute, resources are sorted according to that attribute's
value; if it's a multi-valued attribute, resources are sorted
by the value of the primary attribute, if any, or else the
first value in the list, if any. If the attribute is complex
the attribute name must be a path to a sub-attribute in
standard <xref format="default"
target="attribute-notation">attribute notation</xref> ; e.g.,
<spanx style="verb">sortBy=name.givenName</spanx>. For all
attribute types, if there is no data for the specified <spanx
style="verb">sortBy</spanx> value they are sorted via the
<spanx style="verb">sortOrder</spanx> parameter; i.e., they
are ordered last if ascending and first if descending.</t>
<t hangText="sortOrder:">The order in which the sortBy
parameter is applied. Allowed values are <spanx style="verb">ascending</spanx>
and <spanx style="verb">descending</spanx>. If a value for
sortBy is provided and no sortOrder is specified, the
sortOrder SHALL default to ascending. String type attributes
are case insensitive by default unless the attribute type is
defined as a case exact string. <spanx style="verb">sortOrder</spanx>
MUST sort according to the attribute type; i.e., for <spanx
style="verb">caseIgnore</spanx> attributes, sort the result
using case insensitive, unicode alphabetic sort order, with no
specific locale implied and for caseExact attribute types,
sort the result using case sensitive, Unicode alphabetic sort
order.</t>
</list></t>
</section>
<section anchor="pagination" title="Pagination">
<t>Pagination parameters can be used together to "page through"
large numbers of resources so as not to overwhelm the client or
service provider. Pagination is not session based hence clients
SHOULD never assume repeatable results. For example, a request for
a list of 10 resources beginning with a startIndex of 1 may return
different results when repeated as a resource in the original
result could be deleted or new ones could be added in-between
requests. Pagination parameters and general behavior are derived
from the OpenSearch Protocol <xref target="OpenSearch"/>.</t>
<t>The following table describes the URL pagination
parameters.</t>
<texttable anchor="consumer-pagination-options-table"
title="Pagination Request parameters">
<ttcol align="left">Parameter</ttcol>
<ttcol align="left">Description</ttcol>
<ttcol align="left">Default</ttcol>
<c>startIndex</c>
<c>The 1-based index of the first search result.</c>
<c>1</c>
<c>count</c>
<c>Non-negative Integer. Specifies the desired maximum number of
search results per page; e.g., 10.</c>
<c>None. When specified the service provider MUST not return
more results than specified though MAY return fewer results. If
unspecified, the maximum number of results is set by the service
provider.</c>
</texttable>
<t>The following table describes the query response pagination
attributes specified by the service provider.</t>
<texttable anchor="response-pagination-options-table"
title="Pagination Response Elements">
<ttcol align="left">Element</ttcol>
<ttcol align="left">Description</ttcol>
<c>itemsPerPage</c>
<c>Non-negative Integer. Specifies the number of search results
returned in a query response page; e.g., 10.</c>
<c>totalResults</c>
<c>Non-negative Integer. Specifies the total number of results
matching the client query; e.g., 1000.</c>
<c>startIndex</c>
<c>The 1-based index of the first result in the current set of
search results; e.g., 1.</c>
</texttable>
<t>For example, to retrieve the first 10 Users set the startIndex
to 1 and the count to 10. <figure align="left" alt="" height=""
suppress-title="false" title="" width="">
<artwork align="left" alt="" height="" name="" type=""
width="" xml:space="preserve">
GET /Users?startIndex=1&count=10
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure> <figure align="left" alt="" height=""
suppress-title="false" title="" width="">
<artwork align="left" alt="" height="" name="" type=""
width="" xml:space="preserve">
{
"totalResults":100,
"itemsPerPage":10,
"startIndex":1,
"schemas":["urn:scim:schemas:core:2.0"],
"Resources":[{
...
}]
}
</artwork>
</figure> Given the example above, to continue paging set the
startIndex to 11 and re-fetch; i.e.,
/Users?startIndex=11&count=10</t>
</section>
</section>
<section anchor="query-post"
title="Querying Resources Using HTTP POST">
<t>Clients MAY execute queries without passing parameters on the URL
by using the HTTP POST verb combined with the '/.search' path
extension. The inclusion of '/.search' on the end of a valid SCIM
endpoint SHALL be used to indicate the HTTP POST verb is intended to
be a query operation.</t>
<t>To create a new search result set, a SCIM client sends an HTTP
POST request to the desired SCIM resource endpoint (ending in
'/.search'). The body of the POST request MAY include any of the
parameters as defined in <xref target="query-resources"/>.</t>
<t>Search requests MUST be identified using the following URI:
'urn:scim:schemas:core:2.0:SearchRequest'. The following attributes
are defined for search requests:</t>
<t><list style="hanging">
<t hangText="attributes">A multi-valued list of strings
indicating the names of resource attributes to return in the
response. Attribute names MUST be in standard <xref
format="default" target="attribute-notation">attribute
notation</xref> form. See <xref format="default"
target="addtl-retrieval-query-params">additional retrieval query
parameters</xref>. OPTIONAL.</t>
<t hangText="filter">The filter string used to request a subset
of resources. The filter string MUST be a valid <xref
format="default" target="filtering">filter</xref> expression.
OPTIONAL.</t>
<t hangText="sortBy">A string indicating the attribute whose
value SHALL be used to order the returned responses. The sortBy
attribute MUST be in standard <xref format="default"
target="attribute-notation">attribute notation</xref> form. See
<xref format="default" target="sorting">sorting</xref>.
OPTIONAL.</t>
<t hangText="sortOrder">A string indicating the order in which
the sortBy parameter is applied. Allowed values are "ascending"
and "descending". See <xref format="default"
target="sorting">sorting</xref>. OPTIONAL.</t>
<t hangText="startIndex">An integer indicating the 1-based index
of the first search result. See <xref format="default"
target="pagination">pagination</xref>. OPTIONAL.</t>
<t hangText="count">An integer indicating the desired maximum
number of search results per page. See <xref format="default"
target="pagination">pagination</xref>. OPTIONAL.</t>
</list></t>
<t>After receiving a HTTP POST request, a response is returned as
specified in <xref target="query-resources"/>.</t>
<figure align="left" alt="POST Example" anchor="POSTExample"
title="Example POST Search Request">
<preamble>The following example shows an HTTP POST Search request
with search parameters attributes, filter, and count
included:</preamble>
<artwork align="center" height="13">POST /.search
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:schemas:core:2.0:SearchRequest"],
"attributes": ["displayName", "userName"],
"filter": "displayName sw \"smith\"",
"startIndex": 1,
"count": 10
}</artwork>
</figure>
<figure align="left" anchor="ExampleResponse"
title="Example POST Search Response">
<preamble>A search response is shown with the first page of
results. For brevity reasons, only two matches are shown: one User
and one Group.</preamble>
<artwork align="center">HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/.search
{
"schemas": ["urn:scim:schemas:core:2.0:ListResponse"],
"totalResults":100,
"itemsPerPage":10,
"startIndex":1,
"Resources":[
{
"meta":{
"location":
"https://example.com/Users/2819c223-7f76-413861904646",
"resourceType":"User",
"lastModified": ...
},
"userName":"jsmith",
"displayName":"Smith, James"
},
{
"meta":{
"location":
"https://example.com/Groups/c8596b90-7539-4f20968d1908",
"resourceType":"Group",
"lastModified": ...
},
"displayName":"Smith Family"
},
...
]
} </artwork>
</figure>
</section>
</section>
<section title="Modifying Resources" toc="default">
<t>Resources can be modified in whole or in part via PUT or PATCH,
respectively. Implementers MUST support PUT as specified in <xref
target="RFC2616">Section 9.6</xref> . Resources such as Groups may be
very large hence implementers SHOULD support <xref
target="RFC5789">PATCH </xref> to enable partial resource
modifications.</t>
<section anchor="edit-resource-with-put" title="Modifying with PUT"
toc="default">
<t>PUT performs a full update. Clients MAY retrieve the entire
resource in advance, add the desired modifications and use HTTP PUT
which will overwrite all previously stored data. Since the PUT
request performs a full update, clients MAY send attributes of the
retrieved resource and the service provider MUST process according
to attribute mutability as follows:<list style="hanging">
<t hangText="readWrite, writeOnly">Any values provided SHALL
replace the existing attribute values. Omitting the attribute or
specific values means the attribute or specific value SHALL be
removed;</t>
<t hangText="immutable">If values are provided for elements
already set in the attribute they MUST match existing data or an
error is returned. If the service provider has no existing
values, a new value(s) MAY be specified; and,</t>
<t hangText="readOnly">Any values provided (e.g.
meta.resourceType) SHALL be ignored. </t>
</list>If an attribute is "required", the client MUST specify the
attribute in the PUT request. </t>
<t>If a value provided for an immutable attribute with an existing
value is NOT matched, the server SHALL respond with an HTTP response
code of 400 and an apprpriate human readable message indicating an
attempt to change an immutable attribute.</t>
<t>Unless otherwise specified a successful PUT operation returns a
200 OK response code and the entire resource within the response
body, enabling the client to correlate the client's and Provider's
views of the updated resource. Example:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PUT /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara",
"middleName":"Jane"
},
"emails":[
{
"value":"bjensen@example.com"
},
{
"value":"babs@jensen.org"
}
]
}
</artwork>
</figure>
<t>The service responds with the entire, updated User</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
ETag: W/"b431af54f0671a2"
Location:"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara",
"middleName":"Jane"
},
"emails":[
{
"value":"bjensen@example.com"
},
{
"value":"babs@jensen.org"
}
],
"meta": {
"resourceType":"User",
"created":"2011-08-08T04:56:22Z",
"lastModified":"2011-08-08T08:00:12Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"b431af54f0671a2\""
}
}
</artwork>
</figure>
</section>
<section anchor="edit-resource-with-patch"
title="Modifying with PATCH" toc="default">
<t>PATCH is OPTIONAL. PATCH enables clients to send only those
attributes requiring modification, reducing network and processing
overhead. Attributes may be deleted, replaced, merged, or added in a
single request.</t>
<t>The body of a PATCH request MUST contain a partial resource with
the desired modifications. The server MUST return either a 200 OK
response code and the entire resource (subject to the "attributes"
query parameter - see <xref format="default"
target="addtl-retrieval-query-params">Additional Retrieval Query
Parameters</xref>) within the response body, or a 204 No Content
response code and the appropriate response headers for a successful
PATCH request. The server MUST return a 200 OK if the "attributes"
parameter is specified on the request.</t>
<t>The server MUST process a PATCH request by first removing any
attributes specified in the meta.attributes Sub-Attribute (if
present) and then merging the attributes in the PATCH request body
into the resource.</t>
<t>The meta.attributes Sub-Attribute MAY contain a list of
attributes to be removed from the resource. If the PATCH request
body contains an attribute that is present in the meta.attributes
list, the attribute on the resource is replaced with the value from
the PATCH body. If the attribute is complex the attribute name must
be a path to a Sub-Attribute in standard <xref format="default"
target="attribute-notation">attribute notation</xref>; e.g.,
name.givenName.</t>
<t>Attributes that exist in the PATCH request body but not in the
meta.attributes Sub-Attribute will be either be updated or added to
the resource according to the following rules.</t>
<t><list style="hanging">
<t hangText="Singular attributes:">Singular attributes in the
PATCH request body replace the attribute on the resource.</t>
<t hangText="Complex attributes:">Complex Sub-Attribute values
in the PATCH request body are merged into the complex attribute
on the resource.</t>
<t hangText="Multi-valued attributes:">An attribute value in the
PATCH request body is added to the value collection if the value
does not exist and merged if a matching value is present. Values
are matched by comparing the value Sub-Attribute from the PATCH
request body to the value Sub-Attribute of the resource.
Attributes that do not have a value Sub-Attribute; e.g.,
addresses, or do not have unique value Sub-Attributes cannot be
matched and must instead be deleted then added. Specific values
can be removed from a resource by adding an "operation"
Sub-Attribute with the value "delete" to the attribute in the
PATCH request body. As with adding/updating attribute value
collections, the value to delete is determined by comparing the
value Sub-Attribute from the PATCH request body to the value
Sub-Attribute of the resource. Attributes that do not have a
value Sub-Attribute or that have a non-unique value
Sub-Attribute are matched by comparing all Sub-Attribute values
from the PATCH request body to the Sub-Attribute values of the
resource. A delete operation is ignored if the attribute's name
is in the meta.attributes list. If the requested value to delete
does not match a unique value on the resource the server MAY
return a HTTP 400 error.</t>
</list></t>
<t>The following example shows how to add a member to a group:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"members": [
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"value": "2819c223-7f76-453a-919d-413861904646"
}
]
}
</artwork>
</figure>
<t>The "display" Sub-Attribute in this request is optional since the
value attribute uniquely identifies the user to be added. If the
user was already a member of this group, no changes should be made
to the resource and a success response should be returned. The
server responds with either the entire updated Group or no response
body:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 204 No Content
Authorization: Bearer h480djs93hd8
ETag: W/"b431af54f0671a2"
Location: "https://example.com/v2/Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce"
</artwork>
</figure>
<t>The following example shows how to remove a member from a group.
As with the previous example, the "display" Sub-Attribute is
optional. If the user was not a member of this group, no changes
should be made to the resource and a success response should be
returned.</t>
<t>Note that server responses have been omitted for the rest of the
PATCH examples.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"members": [
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"value": "2819c223-7f76-453a-919d-413861904646",
"operation": "delete"
}
]
}
</artwork>
</figure>
<t>The following example shows how to remove all members from a
group:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"meta": {
"attributes": [
"members"
]
}
}
</artwork>
</figure>
<t>The following example shows how to replace all of the members of
a group with a different members list:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"meta": {
"attributes": [
"members"
]
},
"members": [
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"value": "2819c223-7f76-453a-919d-413861904646"
},
{
"display": "James Smith",
"$ref": "https://example.com/v2/Users/08e1d05d-121c-4561-8b96-473d93df9210",
"value": "08e1d05d-121c-4561-8b96-473d93df9210"
}
]
}
</artwork>
</figure>
<t>The following example shows how to add a member to and remove a
member from a Group in a single request:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Groups/acbf3ae7-8463-4692-b4fd-9b4da3f908ce
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"members": [
{
"display": "Babs Jensen",
"$ref": "https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"value": "2819c223-7f76-453a-919d-413861904646",
"operation": "delete"
},
{
"display": "James Smith",
"$ref": "https://example.com/v2/Users/08e1d05d-121c-4561-8b96-473d93df9210",
"value": "08e1d05d-121c-4561-8b96-473d93df9210"
}
]
}
</artwork>
</figure>
<t>The following example shows how to change a User's primary email.
If the User already has the email address, it is made the primary
address and the current primary address (if present) is made
non-primary. If the User does not already have the email address, it
is added and made the primary address.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"emails": [
{
"value": "bjensen@example.com",
"primary": true
}
]
}
</artwork>
</figure>
<t>The following example shows how to change a User's address. Since
address does not have a value Sub-Attribute, the existing address
must be removed and the modified address added.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"addresses": [
{
"type": "work",
"streetAddress": "100 Universal City Plaza",
"locality": "Hollywood",
"region": "CA",
"postalCode": "91608",
"country": "US",
"formatted": "100 Universal City Plaza\nHollywood, CA 91608 US",
"primary": true,
"operation": "delete"
},
{
"type": "work",
"streetAddress": "911 Universal City Plaza",
"locality": "Hollywood",
"region": "CA",
"postalCode": "91608",
"country": "US",
"formatted": "911 Universal City Plaza\nHollywood, CA 91608 US",
"primary": true
}
]
}
</artwork>
</figure>
<t>The following example shows how to change a User's nickname:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"nickName": "Barbie"
}
</artwork>
</figure>
<t>The following example shows how to remove a User's nickname:</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"meta": {
"attributes": [
"nickName"
]
}
}
</artwork>
</figure>
<t>The following example shows how to change a User's familyName.
This only updates the familyName and formatted on the "name" complex
attribute. Any other name Sub-Attributes on the resource remain
unchanged.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"name": {
"formatted": "Ms. Barbara J Jensen III",
"familyName": "Jensen"
}
}
</artwork>
</figure>
<t>The following example shows how to remove a complex Sub-Attribute
and an extended schema attribute from a User.</t>
<figure align="left" alt="" height="" suppress-title="false"
title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
PATCH /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
If-Match: W/"a330bc54f0671c9"
{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"meta": {
"attributes": [
"name.formatted",
"urn:hr:schemas:user:age"
]
}
}
</artwork>
</figure>
</section>
</section>
<section anchor="delete-resource" title="Deleting Resources"
toc="default">
<t>Clients request resource removal via DELETE. Service providers MAY
choose not to permanently delete the resource, but MUST return a 404
error code for all operations associated with the previously deleted
Id. Service providers MUST also omit the resource from future query
results. In addition the service provider MUST not consider the
deleted resource in conflict calculation. For example if a User
resource is deleted, a CREATE request for a User resource with the
same userName as the previously deleted resource should not fail with
a 409 error due to userName conflict.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
DELETE /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Authorization: Bearer h480djs93hd8
If-Match: W/"c310cd84f0281b7"
</artwork>
</figure>
<t>In response to a successful delete, the server SHALL respond with
successful HTTP status 204 (No Content). A non-normative example
response:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 204 No Content
</artwork>
</figure>
<t>Example: client attempt to retrieve the previously deleted User</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646
Host: example.com
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>Server Response:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 404 NOT FOUND
{
"schemas": ["urn:scim:schemas:core:2.0:Error"],
"Errors":[
{
"description":"Resource 2819c223-7f76-453a-919d-413861904646 not found",
"code":"404"
}
]
}
</artwork>
</figure>
</section>
<section anchor="bulk-resources" title="Bulk" toc="default">
<t>Bulk is OPTIONAL. The bulk operation enables clients to send a
potentially large collection of resource operations in a single
request. The body of a a bulk operation contains a set of HTTP
resource operations using one of the API supported HTTP methods; i.e.,
POST, PUT, PATCH or DELETE.</t>
<t>Bulk requests are identified using the following URI:
'urn:scim:schemas:core:2.0:BulkRequest'. Bulk responses are identified
using the following URI: 'urn:scim:schemas:core:2.0:BulkResponse'.
Bulk requests and bulk responses share many attributes. Unless
otherwise specified, each attribute below is present in both bulk
requests and bulk responses.</t>
<t>The following Singular Attribute is defined in addition to the
common attributes defined in SCIM core schema.</t>
<t><list style="hanging">
<t hangText="failOnErrors">An Integer specifying the number of
errors that the service provider will accept before the operation
is terminated and an error response is returned. OPTIONAL in a
request. Not valid in a response.</t>
</list></t>
<t>The following Complex Multi-valued Attribute is defined in addition
to the common attributes defined in core schema.</t>
<t><list style="hanging">
<t hangText="Operations">Defines operations within a bulk job.
Each operation corresponds to a single HTTP request against a
resource endpoint. REQUIRED. <list style="hanging">
<t hangText="method">The HTTP method of the current operation.
Possible values are POST, PUT, PATCH or DELETE. REQUIRED.</t>
<t hangText="bulkId">The transient identifier of a newly
created resource, unique within a bulk request and created by
the client. The bulkId serves as a surrogate resource id
enabling clients to uniquely identify newly created resources
in the Response and cross reference new resources in and
across operations within a bulk request. REQUIRED when method
is POST.</t>
<t hangText="version">The current resource version. Version is
REQUIRED if the service provider supports ETags and the method
is PUT, DELETE, or PATCH.</t>
<t hangText="path">The resource's relative path. If the method
is POST the value must specify a resource type endpoint; e.g.,
/Users or /Groups whereas all other method values must specify
the path to a specific resource; e.g.,
/Users/2819c223-7f76-453a-919d-413861904646. REQUIRED in a
request.</t>
<t hangText="data">The resource data as it would appear for a
single POST, PUT or PATCH resource operation. REQUIRED in a
request when method is POST, PUT and PATCH.</t>
<t hangText="location">The resource endpoint URL. REQUIRED in
a response, except in the event of a POST failure.</t>
<t hangText="status">A complex type that contains information
about the success or failure of one operation within the bulk
job. REQUIRED in a response. <list style="hanging">
<t hangText="code">The HTTP response code that would have
been returned if a a single HTTP request would have been
used. REQUIRED.</t>
<t hangText="description">A human readable error message.
REQUIRED when an error occurred.</t>
</list></t>
</list></t>
</list></t>
<t>If a bulk job is processed successfully the HTTP response code 200
OK MUST be returned, otherwise an appropriate HTTP error code MUST be
returned.</t>
<t>The service provider MUST continue performing as many changes as
possible and disregard partial failures. The client MAY override this
behavior by specifying a value for failOnErrors attribute. The
failOnErrors attribute defines the number of errors that the service
provider should accept before failing the remaining operations
returning the response.</t>
<t>To be able to reference a newly created resource the attribute
bulkId MUST be specified when creating new resources. The bulkId is
defined by the client as a surrogate identifier in a POST operation.
The service provider MUST return the same bulkId together with the
newly created resource. The bulkId can then be used by the client to
map the service provider id with the bulkId of the created
resource.</t>
<t>There can be more then one operation per resource in each bulk job.
The Service client MUST take notice of the unordered structure of JSON
and the service provider can process operations in any order. For
example, if the Service client sends two PUT operations in one
request, the outcome is non-deterministic.</t>
<t>The service provider response MUST include the result of all
processed operations. A location attribute that includes the
resource's end point MUST be returned for all operations excluding
failed POSTs. The status attribute includes information about the
success or failure of one operation within the bulk job. The attribute
status MUST include the code attribute that holds the HTTP response
code that would have been returned if a single HTTP request would have
been used. If an error occurred the status MUST also include the
description attribute containing a human readable explanation of the
error.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
"status": {
"code": "201"
}
</artwork>
</figure>
<t>The following is an example of a status in a failed operation.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
"status": {
"code": "400",
"description": "Request is unparseable, syntactically incorrect, or violates schema."
}</artwork>
</figure>
<t>The following example shows how to add, update, and remove a user.
The failOnErrors attribute is set to '1' indicating the service
provider should return on the first error. The POST operation's bulkId
value is set to 'qwerty' enabling the client to match the new User
with the returned resource id
'92b725cd-9465-4e7d-8c16-01f8e146b87a'.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:schemas:core:2.0:BulkRequest"],
"failOnErrors":1,
"Operations":[
{
"method":"POST",
"path":"/Users",
"bulkId":"qwerty",
"data":{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"userName":"Alice"
}
},
{
"method":"PUT",
"path":"/Users/b7c14771-226c-4d05-8860-134711653041",
"version":"W\/\"3694e05e9dff591\"",
"data":{
"schemas": ["urn:scim:schemas:core:2.0:User"],
"id":"b7c14771-226c-4d05-8860-134711653041",
"userName":"Bob"
}
},
{
"method":"PATCH",
"path":"/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"version":"W\/\"edac3253e2c0ef2\"",
"data":{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"userName":"Dave",
"meta":{
"attributes":[
"nickName"
]
}
}
},
{
"method":"DELETE",
"path":"/Users/e9025315-6bea-44e1-899c-1e07454e468b",
"version":"W\/\"0ee8add0a938e1a\""
}
]
}</artwork>
</figure>
<t>The service provider returns the following response.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
{
"schemas": ["urn:scim:schemas:core:2.0:BulkResponse"],
"Operations": [
{
"location": "https://example.com/v2/Users/92b725cd-9465-4e7d-8c16-01f8e146b87a",
"method": "POST",
"bulkId": "qwerty",
"version": "W\/\"oY4m4wn58tkVjJxK\"",
"status": {
"code": "201"
}
},
{
"location": "https://example.com/v2/Users/b7c14771-226c-4d05-8860-134711653041",
"method": "PUT",
"version": "W\/\"huJj29dMNgu3WXPD\"",
"status": {
"code": "200"
}
},
{
"location": "https://example.com/v2/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"method": "PATCH",
"version": "W\/\"huJj29dMNgu3WXPD\"",
"status": {
"code": "200"
}
},
{
"location": "https://example.com/v2/Users/e9025315-6bea-44e1-899c-1e07454e468b",
"method": "DELETE",
"status": {
"code": "204"
}
}
]
}</artwork>
</figure>
<t>The following response is returned if an error occurred when
attempting to create the User 'Alice'. The service provider stops
processing the bulk operation and immediately returns a response to
the client. The response contains the error and any successful results
prior to the error.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
{
"schemas": ["urn:scim:schemas:core:2.0:BulkResponse"],
"Operations": [
{
"method": "POST",
"bulkId": "qwerty",
"status": {
"code": "400",
"description": "Request is unparseable, syntactically incorrect, or violates schema."
}
}
]
}</artwork>
</figure>
<t>If the failOnErrors attribute is not specified or the service
provider has not reached the error limit defined by the client the
service provider will continue to process all operations. The
following is an example in which all operations failed.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
{
"schemas": ["urn:scim:schemas:core:2.0:BulkResponse"],
"Operations": [
{
"method": "POST",
"bulkId": "qwerty",
"status": {
"code": "400",
"description": "Request is unparseable, syntactically incorrect, or violates schema."
}
},
{
"location": "https://example.com/v2/Users/b7c14771-226c-4d05-8860-134711653041",
"method": "PUT",
"status": {
"code": "412",
"description": "Failed to update as user changed on the server since you last retrieved it."
}
},
{
"location": "https://example.com/v2/Users/5d8d29d3-342c-4b5f-8683-a3cb6763ffcc",
"method": "PATCH",
"status": {
"code": "412",
"description": "Failed to update as user changed on the server since you last retrieved it."
}
},
{
"location": "https://example.com/v2/Users/e9025315-6bea-44e1-899c-1e07454e468b",
"method": "DELETE",
"status": {
"code": "404",
"description": "Specified resource; e.g., User, does not exist."
}
}
]
}</artwork>
</figure>
<t>The client can, within one bulk operation, create a new User, a new
Group and add the newly created User to the newly created Group. In
order to add the new User to the Group the client must use the
surrogate id attribute, bulkId, to reference the User. The bulkId
attribute value must be pre-pended with the literal "bulkId:"; e.g.,
if the bulkId is 'qwerty' the value is “bulkId:qwerty”. The service
provider MUST replace the string “bulkId:qwerty” with the permanent
resource id once created.</t>
<t>The following example creates a User with the userName 'Alice' and
a Group with the displayName 'Tour Guides' with Alice as a member.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:schemas:core:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Users",
"bulkId": "qwerty",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:User"],
"userName": "Alice"
}
},
{
"method": "POST",
"path": "/Groups",
"bulkId": "ytrewq",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Tour Guides",
"members": [
{
"type": "user",
"value": "bulkId:qwerty"
}
]
}
}
]
}</artwork>
</figure>
<t>The service provider returns the following response.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
{
"schemas": ["urn:scim:schemas:core:2.0:BulkResponse"],
"Operations": [
{
"location": "https://example.com/v2/Users/92b725cd-9465-4e7d-8c16-01f8e146b87a",
"method": "POST",
"bulkId": "qwerty",
"version": "W\/\"4weymrEsh5O6cAEK\"",
"status": {
"code": "201"
}
},
{
"location": "https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a",
"method": "POST",
"bulkId": "ytrewq",
"version": "W\/\"lha5bbazU3fNvfe5\"",
"status": {
"code": "201"
}
}
]
}</artwork>
</figure>
<t>A subsequent request for the 'Tour Guides' Group
('e9e30dba-f08f-4109-8486-d5c6a331660a') returns the following:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a
ETag: W/"lha5bbazU3fNvfe5"
{
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"id": "e9e30dba-f08f-4109-8486-d5c6a331660a",
"displayName": "Tour Guides",
"meta": {
"resourceType": "Group",
"created": "2011-08-01T18:29:49.793Z",
"lastModified": "2011-08-01T20:31:02.315Z",
"location": "https://example.com/v2/Groups/e9e30dba-f08f-4109-8486-d5c6a331660a",
"version": "W\/\"lha5bbazU3fNvfe5\""
},
"members": [
{
"value": "92b725cd-9465-4e7d-8c16-01f8e146b87a",
"$ref": "https://example.com/v2/Users/92b725cd-9465-4e7d-8c16-01f8e146b87a",
"type": "User"
}
]
}</artwork>
</figure>
<t>Extensions that include references to other resources MUST be
handled in the same way by the service provider. The following example
uses the bulkId attribute within the enterprise extension managerId
attribute.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:schemas:core:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Users",
"bulkId": "qwerty",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:User"],
"userName": "Alice"
}
},
{
"method": "POST",
"path": "/Users",
"bulkId": "ytrewq",
"data": {
"schemas": [
"urn:scim:schemas:core:2.0:User",
"urn:scim:schemas:extension:enterprise:2.0:User"
],
"userName": "Bob",
"urn:scim:schemas:extension:enterprise:2.0:User": {
"employeeNumber": "11250",
"manager": {
"managerId": "batchId:qwerty",
"displayName": "Alice"
}
}
}
}
]
}</artwork>
</figure>
<t>The service provider MUST try to resolve circular cross references
between resources in a single bulk job but MAY stop after a failed
attempt and instead return the status code 409 Conflict. The following
example exhibits the potential conflict.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas": ["urn:scim:schemas:core:2.0:BulkRequest"],
"Operations": [
{
"method": "POST",
"path": "/Groups",
"bulkId": "qwerty",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group A",
"members": [
{
"type": "group",
"value": "bulkId:ytrewq"
}
]
}
},
{
"method": "POST",
"path": "/Groups",
"bulkId": "ytrewq",
"data": {
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group B",
"members": [
{
"type": "group",
"value": "bulkId:qwerty"
}
]
}
}
]
}</artwork>
</figure>
<t>If the service provider resolved the above circular references the
following is returned from a subsequent GET request.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /v2/Groups?filter=displayName sw 'Group'
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
{
"schemas": ["urn:scim:schemas:core:2.0:ListResponse"],
"totalResults": 2,
"Resources": [
{
"id": "c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group A",
"meta": {
"resourceType": "Group",
"created": "2011-08-01T18:29:49.793Z",
"lastModified": "2011-08-01T18:29:51.135Z",
"location": "https://example.com/v2/Groups/c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"version": "W\/\"mvwNGaxB5SDq074p\""
},
"members": [
{
"value": "6c5bb468-14b2-4183-baf2-06d523e03bd3",
"$ref": "https://example.com/v2/Groups/6c5bb468-14b2-4183-baf2-06d523e03bd3",
"type": "Group"
}
]
},
{
"id": "6c5bb468-14b2-4183-baf2-06d523e03bd3",
"schemas": ["urn:scim:schemas:core:2.0:Group"],
"displayName": "Group B",
"meta": {
"resourceType": "Group",
"created": "2011-08-01T18:29:50.873Z",
"lastModified": "2011-08-01T18:29:50.873Z",
"location": "https://example.com/v2/Groups/6c5bb468-14b2-4183-baf2-06d523e03bd3",
"version": "W\/\"wGB85s2QJMjiNnuI\""
},
"members": [
{
"value": "c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"$ref": "https://example.com/v2/Groups/c3a26dd3-27a0-4dec-a2ac-ce211e105f97",
"type": "Group"
}
]
}
]
}</artwork>
</figure>
<t>The service provider MUST define the maximum number of operations
and maximum payload size a client may send in a single request. If
either limits are exceeded the service provider MUST return the HTTP
response code 413 Request Entity Too Large. The returned response MUST
specify the limit exceeded in the body of the error response.</t>
<t>The following example the client sent a request exceeding the
service provider's max payload size of 1 megabyte.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /v2/Bulk
Host: example.com
Accept: application/json
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: 4294967296
…</artwork>
</figure>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 413 Request Entity Too Large
Content-Type: application/json
Location: https://example.com/v2/Bulk/yfCrVJhFIJagAHj8
{
"schemas":["urn:scim:schemas:core:2.0:Error"],
"Errors":[
{
"description":"The size of the bulk operation exceeds the maxPayloadSize (1048576).",
"code":"413"
}
]
}
</artwork>
</figure>
</section>
<section anchor="io-format" title="Data Input/Output Formats">
<t>Clients MUST specify the format in which the data is submitted via
the <xref target="RFC2616">Section 14.17 HTTP header
content-type</xref> and MAY specify the desired response data format
via an HTTP Accept Header; e.g.,"Accept: application/json" or via URI
suffix; e.g., <figure align="left" alt="" height=""
suppress-title="false" title="" width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646.json
Host: example.com
</artwork>
</figure></t>
<t>Service providers MUST support the Accept Headers "Accept:
application/json" for <xref target="RFC4627"/>. The format defaults to
JSON if no format is specified.</t>
<t>Singular attributes are encoded as string name-value-pairs in JSON;
e.g.,</t>
<figure>
<artwork>
"attribute": "value"
</artwork>
</figure>
<t>Multi-valued attributes in JSON are encoded as arrays; e.g.,</t>
<figure>
<artwork>
"attributes": [ "value1", "value2" ]
</artwork>
</figure>
<t>Elements with nested elements are represented as objects in JSON;
e.g,</t>
<figure>
<artwork>
"attribute": { "subattribute1": "value1", "subattribute2": "value2" }
</artwork>
</figure>
</section>
<section anchor="addtl-retrieval-query-params"
title="Additional retrieval query parameters" toc="default">
<t>Clients MAY request a partial resource representation on any
operation that returns a resource within the response by specifying
the URL query parameter 'attributes'. When specified, each resource
returned MUST contain the minimal set of resource attributes and MUST
contain no other attributes or Sub-Attributes than those explicitly
requested. The query parameter attributes value is a comma separated
list of resource attribute names in standard <xref format="default"
target="attribute-notation">attribute notation</xref> form (e.g.
userName, name, emails).</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646?attributes=userName
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
</artwork>
</figure>
<t>Giving the response</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 200 OK
Content-Type: application/json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"a330bc54f0671c9"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"userName":"bjensen",
"meta":{
"resourceType": "User",
"created":"2011-08-01T18:29:49.793Z",
"lastModified":"2011-08-01T18:29:49.793Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"a330bc54f0671c9\""
}
}
</artwork>
</figure>
</section>
<section anchor="attribute-notation" title="Attribute Notation">
<t>All operations share a common scheme for referencing simple and
complex attributes. In general, attributes are identified by prefixing
the attribute name with its schema URN separated by a ':' character;
e.g., the core User resource attribute 'userName' is identified as
'urn:scim:schemas:core:2.0:User:userName'. Clients MAY omit core
schema attribute URN prefixes though MUST fully qualify extended
attributes with the associated resource URN; e.g., the attribute 'age'
defined in 'urn:hr:schemas:user' is fully encoded as
'urn:hr:schemas:user:age'. A Complex attributes' Sub-Attributes are
referenced via nested, dot ('.') notation; i.e., {urn}:{Attribute
name}.{Sub-Attribute name}. For example, the fully qualified path for
a User's givenName is urn:scim:schemas:core:2.0:User:name.givenName
All facets (URN, attribute and Sub-Attribute name) of the fully
encoded Attribute name are case insensitive.</t>
</section>
<section title="HTTP Response Codes">
<t>The SCIM Protocol uses the response status codes defined in HTTP
<xref target="RFC2616"> Section 10</xref> to indicate operation
success or failure. In addition to returning a HTTP response code
implementers MUST return the errors in the body of the response in the
client requested format containing the error response and, per the
HTTP specification, human-readable explanations. Error responses are
identified using the following URI: 'urn:scim:schemas:core:2.0:Error'.
The following multi-valued attribute is defined in addition to those
attributes defined in SCIM Core Schema:</t>
<t><list style="hanging">
<t hangText="Errors">The list of errors encountered by the service
provider. The value attribute is a complex type with the following
sub-attributes. <list style="hanging">
<t hangText="description">A human-readable explanation of the
error. REQUIRED.</t>
<t hangText="code">A string indicating the HTTP response code.
REQUIRED.</t>
</list></t>
</list></t>
<t>Implementers SHOULD handle the identified errors as described
below.</t>
<texttable anchor="http-error-handling-table"
title="Defined error cases">
<ttcol align="left">Code</ttcol>
<ttcol align="left">Applicability</ttcol>
<ttcol align="left">Suggested Explanation</ttcol>
<c>307 TEMPORARY REDIRECT</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>The client is directed to repeat the same HTTP request at the
location identified. The client SHOULD NOT use the location provided
in the response as a permanent reference to the resource and SHOULD
continue to use the original request URI <xref
target="I-D.ietf-httpbis-p2-semantics"/>.</c>
<c>308 PERMANENT REDIRECT</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>The client is directed to repeat the same HTTP request at the
location identified. The client SHOULD use the location provided in
the response as the permanent reference to the resource <xref
target="I-D.reschke-http-status-308"/>.</c>
<c>400 BAD REQUEST</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Request is unparseable, syntactically incorrect, or violates
schema</c>
<c>401 UNAUTHORIZED</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Authorization failure</c>
<c>403 FORBIDDEN</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Server does not support requested operation</c>
<c>404 NOT FOUND</c>
<c>GET, PUT, PATCH, DELETE</c>
<c>Specified resource; e.g., User, does not exist</c>
<c>409 CONFLICT</c>
<c>POST, PUT, PATCH, DELETE</c>
<c>The specified version number does not match the resource's latest
version number or a service provider refused to create a new,
duplicate resource</c>
<c>412 PRECONDITION FAILED</c>
<c>PUT, PATCH,D ELETE</c>
<c>Failed to update as resource {id} changed on the server last
retrieved</c>
<c>413 REQUEST ENTITY TOO LARGE</c>
<c>POST</c>
<c>{"maxOperations": 1000,"maxPayload": 1048576}</c>
<c>500 INTERNAL SERVER ERROR</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>An internal error. Implementers SHOULD provide descriptive
debugging advice</c>
<c>501 NOT IMPLEMENTED</c>
<c>GET, POST, PUT, PATCH, DELETE</c>
<c>Service Provider does not support the request operation; e.g.,
PATCH</c>
</texttable>
<t>Error example in response to a non-existent GET request.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 404 NOT FOUND
{
"schemas": ["urn:scim:schemas:core:2.0:Error"],
"Errors":[
{
"description":"Resource 2819c223-7f76-453a-919d-413861904646 not found",
"code":"404"
}
]
}
</artwork>
</figure>
</section>
<section anchor="api-versioning" title="API Versioning">
<t>The Base URL MAY be appended with a version identifier as a
separate segment in the URL path. At this time the only valid
identifier is 'v1'. If specified, the version identifier MUST appear
in the URL path immediately preceding the resource endpoint and
conform to the following scheme: the character 'v' followed by the
desired SCIM version number; e.g., a version 'v1' User request is
specified as /v2/Users. When specified service providers MUST perform
the operation using the desired version or reject the request. When
omitted service providers SHOULD perform the operation using the most
recent API supported by the service provider.</t>
</section>
<section anchor="etags" title="Versioning Resources">
<t>The API supports resource versioning via standard HTTP ETags<xref
target="RFC2616"> Section 14.19</xref>. Service providers MAY support
weak ETags as the preferred mechanism for performing conditional
retrievals and ensuring clients do not inadvertently overwrite each
others changes, respectively. When supported SCIM ETags MUST be
specified as an HTTP header and SHOULD be specified within the
'version' attribute contained in the resource's 'meta' attribute.</t>
<t>Example:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /Users HTTP/1.1
Host: example.com
Content-Type: application/json
Authorization: Bearer h480djs93hd8
Content-Length: ...
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"userName":"bjensen",
"externalId":"bjensen",
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
}
}
</artwork>
</figure>
<t>The server responds with an ETag in the response header and meta
structure.</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646
ETag: W/"e180ee84f0671b1"
{
"schemas":["urn:scim:schemas:core:2.0:User"],
"id":"2819c223-7f76-453a-919d-413861904646",
"meta":{
"resourceType":"User",
"created":"2011-08-01T21:32:44.882Z",
"lastModified":"2011-08-01T21:32:44.882Z",
"location":"https://example.com/v2/Users/2819c223-7f76-453a-919d-413861904646",
"version":"W\/\"e180ee84f0671b1\""
},
"name":{
"formatted":"Ms. Barbara J Jensen III",
"familyName":"Jensen",
"givenName":"Barbara"
},
"userName":"bjensen"
}
</artwork>
</figure>
<t>With the returned ETag, clients MAY choose to retrieve the resource
only if the resource has been modified.</t>
<t>Conditional retrieval example using If-None-Match <xref
target="RFC2616">Section 14.26</xref> header:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
GET /Users/2819c223-7f76-453a-919d-413861904646?attributes=displayName
Host: example.com
Accept: application/json
Authorization: Bearer h480djs93hd8
If-None-Match: W/"e180ee84f0671b1"
</artwork>
</figure>
<t>If the resource has not changed the service provider simply returns
an empty body with a 304 "Not Modified" response code.</t>
<t>If the service providers supports versioning of resources the
client MUST supply an If-Match <xref target="RFC2616">Section
14.24</xref> header for PUT and PATCH operations to ensure that the
requested operation succeeds only if the supplied ETag matches the
latest service provider resource; e.g., If-Match:
W/"e180ee84f0671b1"</t>
</section>
<section title="HTTP Method Overloading">
<t>In recognition that some clients, servers and firewalls prevent
PUT, PATCH and DELETE operations a client MAY override the POST
operation by specifying the custom header "X-HTTP-Method-Override"
with the desired PUT, PATCH, DELETE operation. For example:</t>
<figure align="left" alt="" height="" suppress-title="false" title=""
width="">
<artwork align="left" alt="" height="" name="" type="" width=""
xml:space="preserve">
POST /Users/2819c223-7f76-453a-919d-413861904646
X-HTTP-Method-Override: DELETE
</artwork>
</figure>
</section>
</section>
<section anchor="MultiTenancy" title="Multi-Tenancy" toc="default">
<t>A single service provider may expose the SCIM protocol to multiple
clients. Depending on the nature of the service, the clients may have
authority to access and alter resources initially created by other
clients. Alternatively, clients may expect to access disjoint sets of
resources, and may expect that their resources are inaccessible by other
clients. These scenarios are called "multi-tenancy", where each client
is understood to be or represent a "tenant" of the service provider.
Clients may also be multi-tenanted.</t>
<t>The following common cases may occur: <list style="numbers">
<t>All clients share all resources (no tenancy)</t>
<t>Each single client creates and accesses a private subset of
resources (1 client:1 Tenant)</t>
<t>Sets of clients share sets of resources (M clients:1 Tenant)</t>
<t>One client to Multiple Tenants (1 client:M Tenants)</t>
</list> Service providers may implement any subset of the above
cases.</t>
<t>Multi-Tenancy is OPTIONAL. The SCIM protocol does not define a scheme
for multi-tenancy.</t>
<t>The SCIM protocol does not prescribe the mechanisms whereby clients
and service providers interact for: <list style="symbols">
<t>Registering or provisioning Tenants</t>
<t>Associating a subset of clients with a subset of the Tenants</t>
<t>Indicating which tenant is associated with the data in a request
or response, or indicating which Tenant is the subject of a
query</t>
<t>Implementers are encouraged to use mechanisms which comply with
RESTful conventions.</t>
</list></t>
<section anchor="tenantAssoc" title="Associating Clients to Tenants"
toc="default">
<t>The service provider MAY use the authentication mechanism (Section
2) to determine the identity of the client, and thus infer the
associated Tenant.</t>
<t>For implementations where a client is associated with more than one
Tenant, the service provider MAY use one of the following methods for
explicit specification of the Tenant.</t>
<t>If any of these methods of allowing the client to explicitly
specify the Tenant are employed, the service provider should ensure
that access controls are in place to prevent or allow cross-tenant use
cases.</t>
<t>The service provider should consider precedence in cases where a
client may explicitly specify a Tenant while being implicitly
associated with a different Tenant.</t>
<section anchor="tenantURLPrefix" title="URL Prefix Example"
toc="default">
<t>https://www.example.com/Tenants/{tenant_id}/v2/Users</t>
</section>
<section anchor="tenantSubdomain" title="Subdomain Example"
toc="default">
<t>https://{tenant_id}.example.com/v2/Groups</t>
</section>
<section anchor="tenantHeader" title="HTTP Header" toc="default">
<t>The service provider may recognize a {tenant_id} provided by the
client in the HTTP Header "SCIM_TENANT_ID" as the indicator of the
desired target Tenant.</t>
<t>In all of these methods, the {tenant_id} is a unique identifier
for the Tenant as defined by the service provider.</t>
</section>
</section>
<section anchor="tenantIdentifiers"
title="SCIM Identifiers with Multiple Tenants" toc="default">
<t>Considerations for a Multi-Tenant Implementation:</t>
<t>The service provider may choose to implement SCIM ids which are
unique across all resources for all Tenants, but this is not
required.</t>
<t>The externalId, defined by the client, is required to be unique
ONLY within the resources associated with the associated Tenant.</t>
</section>
</section>
<section anchor="Security" title="Security Considerations" toc="default">
<t>The SCIM Protocol is based on HTTP and thus subject to the security
considerations found in Section 15 of <xref target="RFC2616"/>. SCIM
resources (e.g., Users and Groups) can contain sensitive information.
Therefore, SCIM clients and service providers MUST implement TLS. Which
version(s) ought to be implemented will vary over time, and depend on
the widespread deployment and known security vulnerabilities at the time
of implementation. At the time of this writing, TLS version 1.2 <xref
target="RFC5246"/>] is the most recent version, but has very limited
actual deployment, and might not be readily available in implementation
toolkits. TLS version 1.0 [<xref target="RFC2246"/>] is the most widely
deployed version, and will give the broadest interoperability.</t>
</section>
</middle>
<back>
<references title="Normative References">
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.3896.xml' ?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.4627.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.2246.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5246.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.5789.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml/reference.RFC.6750.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-ietf-httpbis-p2-semantics-25.xml'?>
<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.draft-reschke-http-status-308-07.xml'?>
<reference anchor="IANA.Language">
<front>
<title>Language Subtag Registry</title>
<author>
<organization>Internet Assigned Numbers Authority
(IANA)</organization>
</author>
<date year="2005"/>
</front>
<format target="http://www.iana.org/assignments/language-subtag-registry"
type="TXT"/>
</reference>
</references>
<references title="Informative References">
<reference anchor="OpenSearch">
<front>
<title>OpenSearch Protocol 1.1, Draft 5</title>
<author fullname="DeWitt Clinton" initials="D." surname="Clinton">
<organization>A9.org</organization>
</author>
<date/>
</front>
<format target="http://www.opensearch.org/Specifications/OpenSearch/1.1"
type="HTML"/>
</reference>
<reference anchor="Order-Operations">
<front>
<title>Order of Operations: Programming Languages</title>
<author>
<organization>Wikipedia</organization>
</author>
<date/>
</front>
<format target="http://en.wikipedia.org/wiki/Order_of_operations#Programming_languages"
type="HTML"/>
</reference>
</references>
<section title="Contributors">
<t><list style="empty">
<t>Samuel Erdtman (samuel@erdtman.se)</t>
<t>Patrick Harding (pharding@pingidentity.com)</t>
</list></t>
</section>
<section title="Acknowledgments">
<t>The editors would like to acknowledge the contribution and work of
the past draft editors:<list>
<t>Trey Drake, UnboundID</t>
<t>Chuck Mortimore, Salesforce</t>
</list></t>
<t>The editor would like to thank the participants in the the SCIM
working group for their support of this specification.</t>
</section>
<section title="Change Log">
<t>[[This section to be removed prior to publication as an RFC]]</t>
<t>Draft 02 - KG - Addition of schema extensibility</t>
<t>Draft 03 - PH - Revisions based on following tickets:<list>
<t>24 - Add filter negation</t>
<t>39 - Clarification on response for DELETE</t>
<t>42 - Make root searches optional</t>
<t>49 - Add "ew" filter</t>
<t>50 - Filters for multi-valued complex attributes</t>
<t>51 - Search by Schema</t>
<t>53 - Standard use of term client (some was consumer)</t>
<t>55 - Redirect support (3xx)</t>
<t>56 - Make manager attribute consistent with other $ref attrs</t>
<t>57 - Update all "/v1" examples to '/v2"</t>
<t>59 - Fix capitalization per IETF editor practices</t>
<t>60 - Changed <eref> tags to normal <xref> and
<reference> tags</t>
</list></t>
</section>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-24 13:20:08 |