@[toc]
Overview
=======
The API is designed so that you start from a base, find the resource you are interested in using, and gather relationships and attributes from those resources. By and large, you shouldn't construct URLs yourself, because sometimes those URLs may change. Top-level collections (nodes, users, registrations, files) and the detail views of each of those lists will be fine, but anything past that you want to get from the relationships of those resources.
A typical example is that you want to create a node, then add a file into the OSF Storage provider of that node. To do that, you:
1. POST to the [/nodes/](https://api.osf.io/v2/nodes/) resource;
2. Get the [response](https://api.osf.io/v2/nodes/y9jdt/) back including the ID and relationships;
3. Follow the [files relationship](https://api.osf.io/v2/nodes/y9jdt/files/) to get the storage providers attached to that node;
4. Find OSF Storage in that list;
5. Get the links object from the [OSF Storage item](https://api.osf.io/v2/nodes/y9jdt/files/osfstorage/)
6. Find the upload link
7. Use that upload link URL and [PUT a file into OSF Storage using that URL](https://osf.io/y9jdt/wiki/Examples/#File_upload_3).
If you already have a link to a node, you can [GET that node's serialization](https://api.osf.io/v2/nodes/y9jdt/) directly.
Step by Step
============
All right, let's take a look at these items in depth. These examples presume you have [generated a token](https://osf.io/settings/tokens/) and are [using token authentication](https://osf.io/y9jdt/wiki/Examples/#Token_auth_17) for your requests.
1 - POST to /nodes/
-------------------
curl example:
```
## 1. POST to the nodes resource
curl -X "POST" "https://api.osf.io/v2/nodes/" \
-H "Authorization: Bearer Thisisnotarealauthtoken " \
-H "Content-Type: application/vnd.api+json" \
-d "{\"data\":{\"type\":\"nodes\",\"attributes\":{\"title\":\"Typical workflow example\",\"description\":\"This is a node created as an example of how to create a node and upload a file to that node\",\"public\":false,\"category\":\"project\"}}}"
```
2 - Get the response back
-------------------------
You'll get something that looks like the following, though with a different id:
```json
{
"data": {
"relationships": {
"files": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/files/",
"meta": {}
}
}
},
"view_only_links": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/view_only_links/",
"meta": {}
}
}
},
"citation": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/citation/",
"meta": {}
}
}
},
"draft_registrations": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/draft_registrations/",
"meta": {}
}
}
},
"contributors": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/contributors/",
"meta": {}
}
}
},
"forks": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/forks/",
"meta": {}
}
}
},
"root": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/",
"meta": {}
}
}
},
"identifiers": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/identifiers/",
"meta": {}
}
}
},
"comments": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/comments/?filter%5Btarget%5D=d92en",
"meta": {}
}
}
},
"registrations": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/registrations/",
"meta": {}
}
}
},
"node_links": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/node_links/",
"meta": {}
}
}
},
"linked_nodes": {
"links": {
"self": {
"href": "https://api.osf.io/v2/nodes/d92en/relationships/linked_nodes/",
"meta": {}
},
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/linked_nodes/",
"meta": {}
}
}
},
"wikis": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/wikis/",
"meta": {}
}
}
},
"affiliated_institutions": {
"links": {
"self": {
"href": "https://api.osf.io/v2/nodes/d92en/relationships/institutions/",
"meta": {}
},
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/institutions/",
"meta": {}
}
}
},
"children": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/children/",
"meta": {}
}
}
},
"preprints": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/preprints/",
"meta": {}
}
}
},
"logs": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/logs/",
"meta": {}
}
}
}
},
"links": {
"self": "https://api.osf.io/v2/nodes/d92en/",
"html": "https://osf.io/d92en/"
},
"attributes": {
"category": "project",
"fork": false,
"preprint": false,
"description": "This is a node created as an example of how to create a node and upload a file to that node",
"current_user_permissions": [
"read",
"write",
"admin"
],
"date_modified": "2017-01-06T20:45:36.884977",
"title": "Typical workflow example",
"collection": false,
"registration": false,
"date_created": "2017-01-06T20:45:36.884977",
"current_user_can_comment": true,
"node_license": null,
"public": false,
"tags": []
},
"type": "nodes",
"id": "d92en"
}
}
```
3 - Follow the files relationship
---------------------------------
So in all of that, you'll find a section called relationships, and in there, you'll find:
```json
"files": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/files/",
"meta": {}
}
}
}
```
Since the `href` for the files relationship is `https://api.osf.io/v2/nodes/s6c68/files/`, so a GET on that:
```
## Request (2)
curl -X "GET" "https://api.osf.io/v2/nodes/d92en/files/" \
-H "Authorization: Bearer Thisisnotarealauthtoken" \
-H "Content-Type: application/vnd.api+json"
```
4 - Find OSF Storage in that list
---------------------------------
In this example, there should really only be one item in the list, but if you were trying to get a storage provider off an existing node that had some storage addons connected, then you would have to search through to find the OSF Storage object.
```json
{
"relationships": {
"files": {
"links": {
"related": {
"href": "https://api.osf.io/v2/nodes/d92en/files/osfstorage/",
"meta": {}
}
}
}
},
"links": {
"storage_addons": "https://api.osf.io/v2/addons/?filter%5Bcategories%5D=storage",
"upload": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/",
"new_folder": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/?kind=folder"
},
"attributes": {
"node": "d92en",
"path": "/",
"kind": "folder",
"name": "osfstorage",
"provider": "osfstorage"
},
"type": "files",
"id": "d92en:osfstorage"
}
```
5 - Get the links object
------------------------
The links object from the response above is:
```json
"links": {
"storage_addons": "https://api.osf.io/v2/addons/?filter%5Bcategories%5D=storage",
"upload": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/",
"new_folder": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/?kind=folder"
}
```
6 - Find the upload link
------------------------
The upload link is:
`https://files.osf.io/v1/resources/d92en/providers/osfstorage/`
7 - Use that upload link URL to upload the file
------------------------------------------------
The [documentation for the file routes](https://api.osf.io/v2/nodes/XXXXX/files/osfstorage/) says that uploads require query parameters for the kind (file) and the file name.
```
Method: PUT
URL: /links/upload
Query Params: ?kind=file&name={new_file_name}
Body (Raw): <file data (not form-encoded)>
Success: 201 Created + new file representation
```
So the request will look like:
```
## Request (3)
curl -X "PUT" "https://files.osf.io/v1/resources/d92en/providers/osfstorage/?kind=file&name=new_file.txt" \
-H "Authorization: Bearer Thisisnotarealauthtoken" \
-H "Content-Type: application/vnd.api+json" \
-d "This is the entirety of the contents of the file I am uploading. It could have been more, but for an example, a small file seems like a better idea."
```
And you'll get back metadata that looks something like:
```json
{
"data": {
"attributes": {
"extra": {
"version": 1,
"checkout": null,
"downloads": 0,
"hashes": {
"sha256": "f2fcf341553b5467efb5877a729bd507cbbe6d47fcfb1bee11085ecb8051dbcc",
"md5": "c7b1b5105d37498bcb14cba7d99c73ad"
},
"guid": null
},
"kind": "file",
"path": "/5870052e6c613b01fdac5df8",
"modified_utc": "2017-01-06T20:59:26+00:00",
"etag": "16196b720fbf3157b40d52f98e5fa320a14ea1af91dac55fe6b31433a33494d0",
"resource": "d92en",
"created_utc": null,
"materialized": "/new_file.txt",
"name": "new_file.txt",
"size": 148,
"modified": "Fri, 06 Jan 2017 20:59:26 GMT",
"contentType": "application/octet-stream",
"provider": "osfstorage"
},
"links": {
"upload": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/5870052e6c613b01fdac5df8?kind=file",
"move": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/5870052e6c613b01fdac5df8",
"download": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/5870052e6c613b01fdac5df8",
"delete": "https://files.osf.io/v1/resources/d92en/providers/osfstorage/5870052e6c613b01fdac5df8"
},
"id": "osfstorage/5870052e6c613b01fdac5df8",
"type": "files"
}
}
```