-
Notifications
You must be signed in to change notification settings - Fork 109
API v1 Documentation
This version of the DMPRoadmap API complies with the RDA Common Standard Metadata schema v1.0. This schema is a recommendation for the transfer of DMP metadata between systems. The specification was created by the RDA Common Standard Working Group
- Notes
- Quick Guide on How to Use API V1
- Base Url & Request Urls
- Heartbeat
- Authentication
- Authorization
- Pagination
- Retrieve a list of DMP templates
- Create a plan
- Retrieve a list of plans
- Retrieve a plan
- Internal DMPRoadmap errors
- Testing
- DMPRoadmap does not currently support a separate and distinct Project. The Project title and DMP title are the same for now.
- DMPRoadmap does not currently support multiple datasets. This means that all exported DMPs will contain a 'Generic Dataset' until we support multiple datasets.
- DMPRoadmap does not yet support the
ethical_issues
entries. - DMPRoadmap will be moving towards full support of all elements of the RDA standard over the next several years.
The base url <BASE_URL> is the url of the Roadmap tool login page, e.g.,
<BASE_URL> = http://localhost:3000/
<BASE_URL> = https://dmponline.dcc.ac.uk/
<BASE_URL> = https://dmptool.org/
The request url format for all api calls will be a combination of the <BASE_URL> and the api route with optional parameters,
Request URL Format: <BASE_URL>/<API_ROUTE>?
e.g.,
http://localhost:3000/api/v1/templates
The API provides a heartbeat endpoint that can be pinged to determine if it is online. The caller does not need to be authenticated.
Format:
<BASE_URL>/api/v1/heartbeat
Example using curl:
curl -v GET https://localhost:3000/api/v1/heartbeat
The API will respond with an HTTP status of 200 and the following JSON output:
{
"application": "DMPRoadmap",
"source": "GET /api/v1/heartbeat",
"time": "2020-02-13T19:47:04-07:00",
"caller": "::1",
"code": 200,
"message": "OK",
"total_items": 0,
"items": []
}
This version of the API uses JSON Web Token technology to manage a session. It supports access by Users and ApiClients.
Organizational Admins can access the API via their email address and the API token found on their Profile page when logged in. Client applications can access the API via their client_id and client_secret. ApiClients can be managed by Super Admins via the Admin Features -> Api Clients menu.
This endpoint authenticates the User or ApiClient and returns a JSON Web Token that should be used for all further communication with the API.
Format:
<BASE_URL>/api/v1/authenticate
Example ApiClient login:
curl -v -X POST https://localhost:3000/api/v1/authenticate \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d "{\"grant_type\":\"client_credentials\",\"client_id\":\"[api_client client_id]\",\"client_secret\":\"[api_client client_secret]\"}"
Example Organizational Admin login:
curl -v -X POST https://localhost:3000/api/v1/authenticate \
-H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
-H "Accept: application/json" \
-d "{\"grant_type\":\"authorization_code\",\"email\":\"[user email]\",\"code\":\"[user api_token]\"}"
DMPRoadmap will then either return a HTTP 401 Unauthorized if the authentication failed (see JSON Body below) or an HTTP 200 Ok if the request succeeds along with a JSON Web Token:
{
"access_token": "eyJhbGciOiJIUzUxMiIsImtpZCI6IkM4MVV6dG9jaHFGOEhMTWxHbHZRUHZCWnJySmx3UTNfOW1PQkROWUMwUGMifQ.eyJpc3MiOiJEbXBodWI6OkFwcGxpY2F0aW9uIiwiaWF0IjoxNTY3NTM3MDg0LCJqdGkiOiI2YzEyNTVjMC1iOWU4LTRiODgtOGZjZC1kYjlhODJiOWFiMjYiLCJjbGllbnQiOnsiaWQiOiJDODFVenRvY2hxRjhITE1sR2x2UVB2Qlpyckpsd1EzXzltT0JETllDMFBjIiwidG9rZW5fc2VjcmV0IjoiNzZhNzVkMDMtMTVmYy00MDZjLWFhMjMtZmM0N2RkYmY3MDUxIn19.f7w_RV62VY4o058-vTK1mvkO-oVnzOnvydCgH9022U9KxspKmmXN2z-4wIauRKIc8nU74wpW3AccUYE0BqeNvQ",
"token_type":"Bearer",
"expires_in":7200,
"created_at":1567537084
}
The User/ApiClient can begin accessing the other API endpoints once they have been authenticated. They must pass along the JSON Web Token (access_token
in the JSON response above) that they received from the authentication step to verify their identity in subsequent calls to the API.
The token should be sent in the HTTP Headers of each request:
{
"Authorization": "Bearer [access_token]"
}
If any API request is missing the authorization token or the token has expired then an HTTP 401 Unauthorized will be returned along with the following JSON body:
{
"application": "DMPRoadmap",
"source": "POST /api/v1/plans/",
"time": "2020-02-07T14:04:01-07:00",
"caller": "User/ApiClient name",
"code": 401,
"message": "UNAUTHORIZED",
"total_items": 0,
"items": [],
"errors": ["Missing token || Invalid token"],
}
By default all endpoints that return multiple items are paginated. You can specify the default and maximum allowable per_page
in your config/initializers/dmproadmap.rb
file.
The User/ApiClient can specify the page=[n]
and per_page=[n]
values in the query string when they call the endpoint.
Example:
curl -k -v -H "Authorization: Bearer <YOUR AUTHENTICATION TOKEN>" \
-H "Content-Type: application/json" \
http://localhost:3000/api/v1/plans\?created_after\=2017-12-31\&per_page\=50\&page\=1
The JSON response will contain useful information for the caller who can then use them to step through the pages to retrieve the full set of information:
{
"application": "DMPRoadmap",
"source": "GET /api/v1/templates",
"time": "2020-02-07T14:04:01-07:00",
"caller": "User/ApiClient name",
"code": 200,
"message": "OK",
"page": 2,
"per_page": 20,
"total_items": 58,
"prev": "/api/v1/templates?page=1&per_page=20",
"next": "/api/v1/templates?page=3&per_page=20",
"items": [
{ "dmp_template": "<< See above for an example of the templates output >>" },
{ "dmp_template": "<< See above for an example of the templates output >>" }
]
}
An authenticated request can be made to retrieve a list of templates. The templates it returns are either publicly visible funder templates or organizational templates that have been created for your organization. If your organization has customized a funder template, the customized version is returned.
Format:
<BASE_URL>/api/v1/templates
Example using curl:
curl -v -H "Accept: application/json" -H "Authorization: Bearer [access_token]" http://localhost:3000/api/v1/templates
This endpoint accepts a page=[n]
and per_page=[n]
query parameter. See more about pagination above.
{
"application": "DMPRoadmap",
"source": "GET /api/v1/templates",
"time": "2020-05-13T22:23:29-07:00",
"caller": "your User/ApiClient name",
"code": 200,
"message": "OK",
"page": 1,
"per_page": 20,
"total_items": 38,
"next": "/api/v1/templates?page=2&per_page=20",
"items": [
{
"dmp_template": {
"title": "EF - Biochemistry",
"description": "A biochemistry template for the Example Funder",
"version": 3,
"created": "2018-02-13T07:18:08Z",
"modified": "2018-04-18T18:18:36Z",
"affiliation": {
"name": "Example Funder",
"abbreviation": "EF",
"affiliation_id": {
"type": "ror",
"identifier": "https://ror.org/000aaa0000"
}
},
"template_id": {
"type": "dmproadmap",
"identifier": "437"
}
}
}
]
}
If the User is an Admin they can retrieve any plan for their Organization. If an ApiClient, then the plan must have been created by that client (this may change as we define further use cases).
When a plan is created via the API, the individual designated as the 'contact' becomes the owner of the plan. If the email address is already recognized by the system it will simply connect the plan to that user's account. If the email address is not recognized the system will send an invitation to the user and connect them to the new plan.
The default DCC template will be used if you do not specify a template in the extensions
block.
Format:
<BASE_URL>/api/v1/plans
Example using curl:
curl -v -X POST https://localhost:3000/api/v1/plans \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Server-Agent: Your Application Name" \
-H "Authorization: Bearer [Your Authorization Token]"
This endpoint expects you to pass in a RDA Common Standard representation of a DMP as JSON:
{
"total_items": 1,
"items": [{
"dmp": {
"title": "Examination of some interesting topics in biochemistry",
"contact": {
"name": "Jane Doe",
"mbox": "[email protected]",
"affiliation": {
"name": "Example University"
},
"contact_id": {
"type": "orcid",
"identifier": "0000-0000-0000-0000"
}
},
"contributor": [
{
"name": "John Smith",
"mbox": "[email protected]",
"role": [
"https://dictionary.casrai.org/Contributor_Roles/Data_curation",
"https://dictionary.casrai.org/Contributor_Roles/Investigation"
],
"affiliation": {
"name": "University of Nowhere",
"affiliation_id": {
"type": "ror",
"identifier": "https://ror.org/123abc45y"
}
},
"contributor_id": {
"type": "orcid",
"identifier": "https://orcid.org/0000-0000-0000-0000"
}
}
],
"extension": [
{
"dmproadmap": {
"template": {
"id": 3
}
}
}
]
}
}]
}
The minimum amount of information required by DMPRoadmap is a DMP title and a contact email:
{
"total_items": 1,
"items": [{
"dmp": {
"title": "Examination of some interesting topics in biochemistry",
"contact": {
"mbox": "[email protected]"
}
}
}]
}
If a new DMP was successfully created an HTTP 201 Created is returned:
{
"application": "DMPRoadmap",
"source": "POST /api/v1/plans/",
"time": "2020-02-07T14:04:01-07:00",
"caller": "User/ApiClient name",
"code": 201,
"message": "CREATED",
"total_items": 0,
"items": [{
"dmp": "<< See an example of the full DMP JSON below in the 'Retrieve a Plan' section >>"
}],
"errors": [],
}
If the request’s JSON was not properly formatted or does not contain the minimum amount of information to create a new DMP then an HTTP 400 Bad Request will be returned along with the following JSON body:
{
"application": "DMPRoadmap",
"source": "POST /api/v1/plans/",
"time": "2020-02-07T14:04:01-07:00",
"caller": "User/ApiClient name",
"code": 400,
"message": "BAD REQUEST",
"total_items": 0,
"items": [],
"errors": ["dmp title cannot be blank", "invalid JSON format", "contact email cannot be blank", "etc."],
}
An OrgAdmin can retrieve a list of plans for their organization and any plans that are publicly visible. An ApiClient can retrieve a list of plans created that they have created and any plans that are publicly visible.
The list contains an abbreviated version of the RDA common standard schema. Subsequent requests for a specific plan can be made to retrieve the full metadata for the plan.
Format:
<BASE_URL>/api/v1/plans
Example using curl:
curl -v -H "Accept: application/json" -H "Authorization: Bearer [access token]" https://localhost:3000/api/v1/plans
If the request was successful an HTTP 200 is returned along with the following JSON content (only displaying the 1st of 20 results):
{
"application": "DMPRoadmap",
"source": "GET /api/v1/plans",
"time": "2020-06-11T15:32:04-07:00",
"caller": "User/ApiClient name",
"code": 200,
"message": "OK",
"page": 1,
"per_page": 20,
"total_items": 248,
"next": "/api/v1/plans?page=2&per_page=20",
"items": [
{
"dmp": {
"schema": "https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard/tree/master/examples/JSON/JSON-schema/1.0",
"title": "USGS CDR/ECV DMP",
"language": "eng",
"created": "2013-01-07T19:06:11Z",
"modified": "2020-04-27T22:38:23Z",
"ethical_issues_exist": "unknown",
"dmp_id": {
"type": "url",
"identifier": "http://localhost:3000/api/v1/plans/5119"
},
"contact": {
"name": "Jane Doe",
"mbox": "[email protected]",
"affiliation": {
"name": "Example University",
"abbreviation": "EU",
"affiliation_id": {
"type": "ror",
"identifier": "https://ror.org/124abc0000a"
}
}
}
}
}
]
}
An OrgAdmin can retrieve any plan for their organization. An ApiClient can retrieve any plan created by that client. A User/ApiClient can also retrieve any plan whose visibility is set to 'publicly_visible'.
Format:
<BASE_URL>/api/v1/plans/[:id]
Example using curl:
curl -v -H "Accept: application/json" -H "Authorization: Bearer [access_token]" http://localhost:3000/api/v1/plans/123
If the request was successful an HTTP 200 is returned along with the following JSON content:
{
"application": "DMPRoadmap",
"source": "GET /api/v1/plans/123",
"time": "2020-02-07 14:04:01 UTC",
"caller": "User/ApiClient name",
"code": 200,
"message": "OK",
"total_items": 1,
"items": [{
"dmp": {
"schema": "https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard/tree/master/examples/JSON/JSSON-schema/1.0",
"title": "Examination of some interesting topics in biochemistry",
"language": "eng",
"created": "2019-08-19T15:45:07Z",
"modified": "2020-04-24T22:28:22Z",
"ethical_issues_exist": "unknown",
"dmp_id": {
"type": "url",
"identifier": "http://localhost:3000/api/v1/plans/123"
},
"contact": {
"name": "Jane Doe",
"mbox": "[email protected]",
"affiliation": {
"name": "Example University",
"abbreviation": "EU",
"affiliation_id": {
"type": "ror",
"identifier": "https://ror.org/124abc0000a"
}
},
"contact_id": {
"type": "orcid",
"identifier": "0000-0000-0000-0000"
}
},
"contributor": [
{
"name": "John Smith",
"mbox": "[email protected]",
"role": [
"https://dictionary.casrai.org/Contributor_Roles/Data_curation",
"https://dictionary.casrai.org/Contributor_Roles/Investigation"
],
"affiliation": {
"name": "University of Nowhere",
"abbreviation": "UofN",
"affiliation_id": {
"type": "ror",
"identifier": "https://ror.org/123abc45y"
}
},
"contributor_id": {
"type": "orcid",
"identifier": "https://orcid.org/0000-0000-0000-0000"
}
}
],
"project": [
{
"title": "Examination of some interesting topics in biochemistry"
}
],
"dataset": [
{
"title": "DMP Dataset",
"personal_data": "unknown",
"sensitive_data": "unknown",
"dataset_id": {
"type": "url",
"identifier": "http://localhost:3000/api/v1/plans/123"
},
"distribution": [
{
"title": "PDF - Testing our maDMP JSON export",
"data_access": "open",
"download_url": "http://localhost:3000/plans/123/export.pdf",
"format": ["application/pdf"]
}
]
}
],
"extension": [
{
"dmproadmap": {
"template": {
"id": 437,
"title": "EF - Biochemistry"
}
}
}
]
}
}]
}
In situations where the plan does not exist or the caller does not have permission to access the plan, an HTTP 404 is returned:
{
"application": "DMPRoadmap",
"source": "GET /api/v1/plans/123",
"time": "2020-02-07T14:04:01-07:00",
"caller": "User/ApiClient name",
"code": 404,
"message": "NOT FOUND",
"total_items": 0,
"items": [],
"errors": ["dmp could not be found"],
}
In the event that a fatal error is thrown from any of the API endpoints an HTTP 500 Internal Server Error will be returned along with the following JSON body:
{
"application": "DMPRoadmap",
"source": "POST /api/v1/plans/",
"time": "2020-02-07T14:04:01-07:00",
"caller": "User/ApiClient name",
"code": 500,
"message": "INTERNAL SERVER ERROR",
"total_items": 0,
"items": [],
"errors": [],
}
You will need to check your logs to determine the root cause of the fatal error.
The following Ruby code is provided as an example of how one can programmatically authenticate and then access the API. Feel free to use it as a reference.
DMPROADMAP_URL = 'https://my.site.org/api/v1'.freeze
CLIENT_ID = 12345.freeze
CLIENT_SECRET = '1234567890abcdefg'.freeze
DEFAULT_HEADERS = headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Accept': 'application/json',
'Server-Agent': 'My external system'
}.freeze
def retrieve_auth_token
payload = {
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
}
target = "#{DMPROADMAP_URL}/authenticate"
resp = HTTParty.post(target, body: payload, headers: DEFAULT_HEADERS)
response = JSON.parse(resp.body)
return nil unless resp.code == 200
token = response
{
'Authorization': "#{token['token_type']} #{token['access_token']}"
}
end
def retrieve_templates(token:, page: 1)
payload = {
grant_type: 'client_credentials',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
}
target = "#{DMPROADMAP_URL}/templates?page=#{page}"
resp = HTTParty.get(target, headers: DEFAULT_HEADERS.merge(token))
resp.code == 200 ? JSON.parse(resp.body) : nil
end
# Authenticate
token = retrieve_auth_token
puts token.inspect
# Retrieve the public templates
templates = retrieve_templates(token: token)
puts templates.inspect
# Retrieve page 2 of the public templates
templates retrieve_templates(token: token, page: 2).inspect
# You can then add further tasks
- Home
- About
- Development roadmap
- Releases
- Themes
- Google Analytics
- Get involved
- Translations
- Developer guide