Switch edu-ID provides an API that can be queried by registered services or organizations. The API is REST/JSON based and provides a few limited functions needed to deal with Switch edu-ID users.
The following functions are currently available via the Tools API:
In order to get access to the API, please write an e-mail to eduid@switch.ch and mention why your application could benefit from the API. The Switch edu-ID team then will evaluate your request and provide you with an individual set of credentials to query the API.
The API has to be queried with standard HTTP requests via HTTPS. The content type is ignored, but preferrably it is "application/json".
All requests have to be authenticated with HTTP Basic authentication.
Request to the API have to be made with standard HTTP methods. The following methods are currently supported:
The generic format of the request URL is:
https://eduid.ch/api/#version#/#objectType#/#object#
An example request thus could be:
GET https://eduid.ch/api/v1/mail/john.doe%40example.org
The following objectTypes are currently implemented:
All responses (including errors) are returned as JSON objects.
The content-type of the HTTP response is "application/json". The character encoding is "UTF-8".
If an operation is successfull, the HTTP response code 200 is returned. Otherwise, one of the HTTP error codes below is returned.
Standard HTTP Error Codes are used to indicate errors. In particular the following error codes are supported.
In addition to the standard HTTP error code, a JSON object will be returned. It has the format of.
HTTP/1.1 #HTTP-ERROR-CODE# #HTTP-ERROR-MESSAGE#
{
"error": {
"code": #HTTP-ERROR-CODE#,
"message": "#API-ERROR-MESSAGE#"
}
}
An example error thus would be:
HTTP/1.1 404 Not Found
{
"error": {
"code": 404,
"message": "E-mail address inexistent@email.address.org is not yet associated with a SWITCH edu-ID user."
}
}
GET /api/#version#/mail/#object#
Example query: GET https://eduid.ch/api/v1/mail/johnd%40gmail.com
Description: Can be used to check if a particular email address given as #object# is already associated with a Switch edu-ID user or not.
Important: The returned primary email address should exclusively be used for service-internal purposes like account matching. It should not be used to contact users, because they have not given their permission. The given name and surname are only returned to services related to the organisation's linking service. Other services will not receive these values.
Response: An error with code 404 will returned if the email address is not known. Otherwise, the HTTP response code 200 is returned as well as JSON object containing the primary email address, name and the SHA1 hash value of the edu-ID identifier:
{
"mail": "#PRIMARY-EMAIL-ADDRESS#",
"swissEduID.sha1": "#SHA1-HASH-OF-EDU-ID-IDENTIFIER#",
"givenName": "#FIRST-NAME#",
"surname": "#LAST-NAME#"
}
Thus an example response would be:
{
"mail": "john.doe@example.org",
"swissEduID.sha1": "2ce6087ed05fa1c780e9503f21ba7a1917e12345"
}
or for a linking service of a university:
{
"mail": "john.doe@example.org",
"givenName": "John",
"surname": "Doe",
"swissEduID.sha1": "2ce6087ed05fa1c780e9503f21ba7a1917e12345"
}
PUT /api/#version#/swissEduPersonUniqueID/#swissEduPersonUniqueID1#/duplicates/#swissEduPersonUniqueID2#
or
PUT /api/#version#/swissEduID/#swissEduID1#/duplicates/#swissEduID2#
Body arguments:
None
Mandatory arguments: swissEduPersonUniqueID1 and swissEduPersonUniqueID2 or swissEduID and swissEduID2
Example queries:
PUT /api/v1/swissEduPersonUniqueID/123456789@eduid.ch/duplicates/abcdedf789@eduid.ch
PUT /api/v1/swissEduID/12344712-f2d7-4073-af12-1b8407e9b07f/duplicates/5678b65d-315e-420c-8126-2051e43b0d0c
Description: Can be used to make edu-ID aware that two accounts belong to the same person. It then will be checked if these accounts exist and if their names are sufficiently similar. If so, an e-mail is sent to the contact address of both acounts informing that these accounts probably belong to the same person. The message then contains instructions on how to merge the two accounts.
Response: If the operation is successful and two duplicate accounts were detected, the HTTP response code 200 is returned. If a message already has been sent within the past 14 days, the status code 202 is returned but no new e-mail is sent to the account contact addresses.
This function is limited to specific API clients. Please let us know if you need access to this function.
PATCH /api/#version#/swissEduPersonUniqueID/#swissEduPersonUniqueID1#/duplicates/#swissEduPersonUniqueID2#
or
PATCH /api/#version#/swissEduID/#swissEduID1#/duplicates/#swissEduID2#
Body arguments:
None
Mandatory arguments: swissEduPersonUniqueID1 and swissEduPersonUniqueID2 or swissEduID and swissEduID2
Example queries:
PATCH /api/v1/swissEduPersonUniqueID/123456789@eduid.ch/duplicates/abcdedf789@eduid.ch
PATCH /api/v1/swissEduID/12344712-f2d7-4073-af12-1b8407e9b07f/duplicates/5678b65d-315e-420c-8126-2051e43b0d0c
Description: Can be used to merge two accounts belonging to the same person. Switch edu-ID first checks if these accounts exist and if there are any potential issues that prevent an automatic merge (e.g. names are not similar enough or one account has not logged in for a long time). If there are no issues, the merge is performed. Switch edu-ID then uses a heuristic to determine which account to keep (typically the one that has been used more often) and which account is to archive. The user is informed about the merge via e-mail.
Response: If the operation is successful and the two duplicate accounts were merged, the HTTP response code 200 is returned together with a JSON object:
{
"swisseduid": "#swissEduID identifier#",
"status": "#status code#",
"new-swisseduid": "#new swissEduID identifier#",
}
If the user already was merged, a HTTP status code 301 is returned together with the above response.
If the merge could not be performed due to one or more issues, another HTTP status code (e.g. 403, 404 or 500) is returned together with a text message of the cause that prevented the merge.
Please note that the merge of two user accounts can take several seconds to complete.
This function is limited to specific API clients. Please let us know if you need access to this function.
The purpose of this method is to allow an organization to start the creation of a current affiliation for a given edu-ID user identified by his edu-ID identifier value. Issuing a request does not set the affiliation directly but instead triggers an attribute query (by edu-ID Attribute Aggregator) to the specified attribute authority. Only if that query is successful (= personal user attributes are returned), a new affiliation gets set.
This method is to be used in the attribute pull scenario. To create an affiliation in the attribute push scenario please use the Affiliation API.
This function is limited to specific API clients. Please let us know if you need access to this function.
Requests are authenticated with HTTP Basic Authentication. The logic should ensure that affiliations generally can only be triggered by an organisation for their own attribute authority. Some requests (e.g. from Switch) should also be allowed to trigger attribute queries for third party attribute authorities for administrative purposes.
In general, API requests have the following structure:
PUT /api/#version#/#objectType#/#object#/#subObjectType#
with the parameters:
PUT /api/#version#/swissEduID/#swissEduID#/affiliations
{
"entityID":"$entityID",
"swissEduPersonUniqueID":"$swissEduPersonUniqueID",
"validFrom":"$timestamp"
}
Parameters and Arguments:
There are two types of requests, synchronous and asynchronous.
Sending synchronous requests (without the validFrom parameter) immediately results in an attribute query to be sent to the Attribute Authority of the given entity specified using using swissEduID as NameIdentifier.
Asynchronous requests contain a validFrom parameter whose date/time is in the future. The attribute query then is executed the same minute as the date/time provided indicates.
The attribute query is currently a SAML Attribute Query (but later may also be a direct LDAP query to a migrated organisation's LDAP server).
PUT /api/v1/swissEduID/8d3a49fe-b62c-44f5-87ff-f8d828a9375b/affiliations
{
"entityID":"https://aai-logon.ethz.ch/idp/shibboleth",
"swissEduPersonUniqueID":"23wecu324809u@ethz.ch",
"validFrom":"2018-06-26T14:01:21Z"
}
{}: {}: {}: Making requests to the edu-ID API is generally very simple and all that is needed is a web client. Therefore, one can use for example curl, which is available on all operating systems. The general curl command to set an affiliation then would look like:
curl -s -basic -u "${apiusername}:${apipassword}" -X PUT -H "Content-Type: application/json" -d "{\"entityID\":\"${entityID}\",\"validFrom\":\"${timestamp}\"}" "${apiurl}${swissEduID}"
An example request to set an affilation now would look like:
curl -s -basic -u "ethz:1234abcde" -X PUT -H "Content-Type: application/json" -d '{"entityID":"https://aai-logon.ethz.ch/idp/shibboleth", "swissEduPersonUniqueID":"23wecu324809u@ethz.ch"}' "https://eduid.ch/api/v1/swissEduID/8d3a49fe-b62c-44f5-87ff-f8d828a9375b/affiliations"
An example request to set an affilation in the future could therefore look like:
curl -s -basic -u "ethz:1234abcde" -X PUT -H "Content-Type: application/json" -d "{\"entityID\":\"https://aai-logon.ethz.ch/idp/shibboleth\", \"swissEduPersonUniqueID\":\"23wecu324809u@ethz.ch\" ,\"validFrom\":\"2018-06-26T14:01:21Z\"}" "https://eduid.ch/api/v1/swissEduID/8d3a49fe-b62c-44f5-87ff-f8d828a9375b/affiliations"
POST /api/#version#/bulk
Example query: POST https://eduid.ch/api/v1/bulk
Description: This bulk API request can be used to check if a number of edu-ID accounts still exist, if they were deleted or if they were merged. In the latter case, the identifiers of the remaining merged account are returned as well as the users current name and email, even if an account was merged several times.
Request Content: The request body must be of the following format:
{
"action": "check-account-status",
"list": [
{ "swisseduid": "#swissEduID identifier#" },
{ "swisseduid": "#swissEduID identifier#" },
{ "swisseduid": "#swissEduID identifier#" },
{ "swisseduid": "#swissEduID identifier#" },
(...)
]
}
{
"action": "check-account-status",
"list": [
{ "swissedupersonuniqueid": "#swissEduPersonUniqueID identifier#" },
{ "swissedupersonuniqueid": "#swissEduPersonUniqueID identifier#" },
{ "swissedupersonuniqueid": "#swissEduPersonUniqueID identifier#" },
{ "swissedupersonuniqueid": "#swissEduPersonUniqueID identifier#" },
(...)
]
}
{
"action": "check-account-status",
"list": [
{ "swisseduid": "1234ae9c-deeb-46db-914b-8f99213b831a" },
{ "swisseduid": "00000000-0000-0000-00000000000000000" },
{ "swissedupersonuniqueid": "234234@eduid.ch" },
{ "swisseduid": "2389ae9c-deeb-46db-914b-8f99213b831a" }
]
}
With curl such a request can be sent with:
curl -s -basic -u "ethz:1234abcde" -X POST -H "Content-Type: application/json" -d @data-file.json https://eduid.ch/api/v1/bulk
Response: The HTTP response code of a request generally 200. Individual status codes are returned for each queried edu-ID identifier records within the JSON object:
{
"action": "check-account-status",
"results": #number of results#,
"list": [
{ "swisseduid": #,
"status": #status code#,
"new-swisseduid": "#new swissEduID identifier#"},
}
}
]
}
The status codes have the following meaning:
Thus an example response would look like:
{
"action": "check-account-status",
"results": 4,
"list": [
{ "swisseduid": "1234ae9c-deeb-46db-914b-8f99213b831a", "status": 200 },
{ "swisseduid": "00000000-0000-0000-00000000000000000", "status": 404 },
{ "swissedupersonuniqueid": "5234234@eduid.ch", "status": 410 },
{ "swisseduid": "2389ae9c-deeb-46db-914b-8f99213b831a", "status": 301,
"new-swisseduid": "789ae237-c664-4ed2-8e83-2c38e05186e7"},
}
}
]
}