There are several ways to interact with the Handle REST API.

With the API you can:

  • Mint or create new handles
  • Modify existing handles by changing the reference location or adding or removing additional metadata entries
  • Delete handles

This guide explains on how to use the API using a bash shell and scripts.

MacOS users

For MacOS users, please make sure to use the right curl version, otherwise the scripts won't work.

Note: Make sure the curl version is compiled with OpenSSL support on MacOS. The included version in MacOS does not work out of the box. See Troubleshooting for a solution.

Sessions

Handles can be created one by one using independent API calls. If you need to complete more then one API call in a sitting, we recommend initiating a session before making subsequent calls. A session provides the advantage that authorisation only needs to be done once, at the creation of the session. This will greatly speed up the process than when authorisation needs to be completed again for every API call. 

Note: always make sure to close a session after all calls have been completed.

Create a handle using curl

A simple script is shown below, which create a handle for URL http://www.bbc.co.uk:

Use the right port

Always make sure to use the right port in your URL! For test prefixes use port 8003 and for production prefixes use port 8000 up to 8007, depending on what has been communicated to you.

#!/bin/bash

PORT=8003
PID_SERVER=https://epic-pid.storage.surfsara.nl:$PORT/api/handles

#### modify following lines. assuming 310:<PREFIX>/USER01 for authentication 
INDEX=310
PREFIX=<insert your own prefix here>
MY_PATH=<insert path where privkey and certificate are located>
PRIVKEY=${MY_PATH}/${PREFIX}_USER01_${INDEX}_privkey.pem
CERTIFICATE=${MY_PATH}/${PREFIX}_USER01_${INDEX}_certificate_only.pem
#### end modify lines
SUFFIX=`uuidgen`

DATA=`cat <<EOF
{"values":[\
{"index":1,"type":"URL","data":{"format":"string","value":"http://www.bbc.co.uk"}},\
{"index":100,"type":"HS_ADMIN","data":{"format":"admin",\
"value":{"handle":"0.NA/$PREFIX","index":200,"permissions":"011111110011"}}}\
]}
EOF
`

curl -v -k --key $PRIVKEY --cert $CERTIFICATE \
    -H "Content-Type: application/json" \
    -H 'Authorization: Handle clientCert="true"' \
    -X PUT --data $DATA \
    $PID_SERVER/$PREFIX/$SUFFIX

In this script, you need to set your prefix, index and the paths to your private key and certificate-only file. Note that in the data sent with the request the value for the `HS_ADMIN` slot has '0.NA/$PREFIX' for the 'handle' key and always '200' for 'index' key, no matter which user.

There are two headers set in the request:

  • Content type: set to JSON mimetype because the data being sent is formatted in JSON
  • Authorization: set to Handle format and indicating a certificate is used for authentication

Modify a handle using curl

After creation of a new handle, you can modify it using a similar script. Do this to:

  • Update the location the handle refers to, by modifying the value at index 1 of type `URL`
  • Add or modify values at other indices

New values can be added at any index except 1 and 100 which are reserved.

#!/bin/bash

PORT=8003
PID_SERVER=https://epic-pid.storage.surfsara.nl:$PORT/api/handles

#### modify following lines. assuming 310:<PREFIX>/USER01 for authentication 
INDEX=310
PREFIX=<insert my own prefix here>
MY_PATH=<insert path to where privkey and certificate are>
PRIVKEY=${MY_PATH}/${PREFIX}_USER01_${INDEX}_privkey.pem
CERTIFICATE=${MY_PATH}/${PREFIX}_USER01_${INDEX}_certificate_only.pem
#### end modify lines

SUFFIX=yourcreatedhandlesuffix
 
curl -v -k --key $PRIVKEY --cert $CERTIFICATE \
    -H "Content-Type: application/json" \
    -H 'Authorization: Handle clientCert="true"' \
    -X PUT --data \
        '{"values": [
            {"index":2,"type":"SOMETYPE","data":{"format":"string","value":"some metadata value"}},
            {"index":3,"type":"OTHERTYPE","data":{"format":"string","value":"other metadata value"}}
        ]}' \
    $PID_SERVER/$PREFIX/$SUFFIX?index=various

In this script, in addition to what is described in the previous section, adds the value 'some metadata value' at index 2 with type 'SOMETYPE' and does the same for index 3. Note the addition of the parameter 'index=various' to the URL.

Create multiple handles using curl in a session

The session functionality allows the creation, update, delete off handles within one session. The advantage is that authentication only has to be done once.

A simple script which will create 3 handles within one session is:

#!/bin/bash

PID_SERVER="https://epic-pid.storage.surfsara.nl:8003"

############ modify following lines, assuming 310:<PREFIX>/USER01 for authentication ############
INDEX=310
PREFIX=<insert my own prefix here>
MY_PATH=<insert path to where privkey and certificate are>
PRIVKEY=${MY_PATH}/${PREFIX}_USER01_${INDEX}_privkey.pem
CERTIFICATE=${MY_PATH}/${PREFIX}_USER01_${INDEX}_certificate_only.pem
############ end modify lines ##############

# create a session and capture the session id
echo "create a session"
session_resp=$(curl -s -k --url ${PID_SERVER}/api/sessions -X POST)
echo "create session response is: ${session_resp}"
session_id=$(echo $session_resp | awk -F'"' '{print $4}')
echo "create session id is: ${session_id}"

# authenticate the session
echo "authenticate the session"
authentication_resp=$(curl -s -k --url ${PID_SERVER}/api/sessions/this -X PUT --key ${PRIVKEY} --cert ${CERTIFICATE} -H "Content-Type:application/json" -H "Authorization: Handle clientCert="true", sessionId="${session_id}"")
echo "authenticate response is: ${authentication_resp}"

# put a handle
echo "create several handles"
create_resp=$(curl -s -k --url ${PID_SERVER}/api/handles/${PREFIX}/session_test_001 -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization: Handle sessionId="${session_id}"" -d  '{"values": [{"index":1,"type":"URL","data":{"format":"string","value":"http://www.test.com"}},{"index":100,"type":"HS_ADMIN","data":{"format":"admin","value":{"handle":"0.NA/${PREFIX}","index":200,"permissions":"011111110011"}}}]}')
echo "create handle 1 response is: ${create_resp}"

# put a second handle
create_resp=$(curl -s -k --url ${PID_SERVER}/api/handles/${PREFIX}/session_test_002 -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization: Handle sessionId="${session_id}"" -d  '{"values": [{"index":1,"type":"URL","data":{"format":"string","value":"http://www.test.com"}},{"index":100,"type":"HS_ADMIN","data":{"format":"admin","value":{"handle":"0.NA/${PREFIX}","index":200,"permissions":"011111110011"}}}]}')
echo "create handle 2 response is: ${create_resp}"

# put a third handle
create_resp=$(curl -s -k --url ${PID_SERVER}/api/handles/${PREFIX}/session_test_003 -X PUT -H 'Content-Type: application/json' -H 'Accept: application/json' -H "Authorization: Handle sessionId="${session_id}"" -d  '{"values": [{"index":1,"type":"URL","data":{"format":"string","value":"http://www.test.com"}},{"index":100,"type":"HS_ADMIN","data":{"format":"admin","value":{"handle":"0.NA/${PREFIX}","index":200,"permissions":"011111110011"}}}]}')
echo "create handle 3 response is: ${create_resp}"

# verify session
echo "verify the session"
verify_rep=$(curl -s -k --url ${PID_SERVER}/api/sessions/this -X GET -H "Content-Type:application/json" -H "Authorization: Handle sessionId="${session_id}"")
echo "verify session response is: ${verify_rep}"

# delete session
echo "delete the session"
delete_resp=$(curl -s -k --url ${PID_SERVER}/api/sessions/this -X DELETE -H "Content-Type:application/json" -H "Authorization: Handle sessionId="${session_id}"" --write-out %{http_code} --output /dev/null)
echo "delete session http(s) response should be 204 and is: ${delete_resp}"

# verify session
echo "verify the session"
verify_rep=$(curl -s -k --url ${PID_SERVER}/api/sessions/this -X GET -H "Content-Type:application/json" -H "Authorization: Handle sessionId="${session_id}"")
echo "verify session response should be empty and is: ${verify_rep}"
Note: never forget to close the session after opening it

List handles for a prefix using curl

It is possible to list the handles which are present for a specific prefix. You will need access to the prefix to do this. For example:

#!/bin/bash

PID_SERVER=https://epic-pid.storage.surfsara.nl:8003/api/handles

#### modify following lines. assuming 310:<PREFIX>/USER01 for authentication
INDEX=310
PREFIX=<insert your own prefix here>
MY_PATH=<insert path where privkey and certificate are located>
PRIVKEY=${MY_PATH}/${PREFIX}_USER01_${INDEX}_privkey.pem
CERTIFICATE=${MY_PATH}/${PREFIX}_USER01_${INDEX}_certificate_only.pem
#### end modify lines

curl -v -k --key $PRIVKEY --cert $CERTIFICATE -H "Content-Type: application/json" -H 'Authorization: Handle clientCert="true"' -X GET $PID_SERVER?prefix=$PREFIX\&pageSize=10000\&page=0
curl -v -k --key $PRIVKEY --cert $CERTIFICATE -H "Content-Type: application/json" -H 'Authorization: Handle clientCert="true"' -X GET $PID_SERVER?prefix=$PREFIX\&pageSize=10000\&page=1
...
curl -v -k --key $PRIVKEY --cert $CERTIFICATE -H "Content-Type: application/json" -H 'Authorization: Handle clientCert="true"' -X GET $PID_SERVER?prefix=$PREFIX\&pageSize=10000\&page=n

This way you are able to retrieve all handles created for this prefix

Note: Please do NOT list more than 10.000 handles at a time. Otherwise the handle server will be overflowed!

Note: do NOT forget the "\" in front of the "&" signs. Otherwise it will be done in the background and the pageSize and page will not be taken in to account!


See the EUDAT Training GitHub repository for more examples.