Skip to content

Fix curl example #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
# The WeTransfer Public API documentation

<p align="center">
<!-- <img src="assets/artwork.jpg" alt="WeTransfer API Docs" width="100%" /> -->
<br>
<img src="https://img.shields.io/badge/License-MIT-yellow.svg?style=flat" />
</p>

Getting Started
---------------
## Getting Started

### Prerequisites

You're going to need:

- **Linux or OS X** Windows may work, but is unsupported.
- **Ruby, version 2.3.1 or newer**
- **Bundler** If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal.
- **Linux or OS X** - Windows may work, but is unsupported.
- **Ruby** - version 2.3.1 or newer
- **Bundler** - If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal.

### Getting Set Up
## Getting Set Up

Initialize and start the docs:

Expand All @@ -26,10 +27,12 @@ bundle exec middleman server

You can now see the docs at http://localhost:4567. Whoa! That was fast!

### Building static files
## Building static files

To create an exportable set of files, run the following command:

`bundle exec middleman build --no-clean`
```shell
bundle exec middleman build --no-clean
```

This will output the static files in the `/docs` folder.
Binary file modified docs/images/sdks/c-sharp-6c75ce29.svg.gz
Binary file not shown.
Binary file modified docs/images/sdks/node-js-df9dffeb.svg.gz
Binary file not shown.
Binary file modified docs/images/sdks/php-ab3973ac.svg.gz
Binary file not shown.
Binary file modified docs/images/sdks/python-dc794a59.svg.gz
Binary file not shown.
Binary file modified docs/images/sdks/r-c8f72e0e.svg.gz
Binary file not shown.
Binary file modified docs/images/sdks/ruby-88f255a7.svg.gz
Binary file not shown.
Binary file modified docs/images/sdks/swift-b38afa16.svg.gz
Binary file not shown.
171 changes: 116 additions & 55 deletions docs/index.html

Large diffs are not rendered by default.

Binary file modified docs/index.html.gz
Binary file not shown.
Binary file modified docs/javascripts/all-2fffc1ac.js.gz
Binary file not shown.
Binary file modified docs/javascripts/all_nosearch-e047639d.js.gz
Binary file not shown.
Binary file modified docs/stylesheets/screen-e44caafe.css.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/c-sharp-6c75ce29.svg.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/node-js-df9dffeb.svg.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/php-ab3973ac.svg.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/python-dc794a59.svg.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/r-c8f72e0e.svg.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/ruby-88f255a7.svg.gz
Binary file not shown.
Binary file modified docs/v1/images/sdks/swift-b38afa16.svg.gz
Binary file not shown.
Binary file modified docs/v1/index.html.gz
Binary file not shown.
Binary file modified docs/v1/javascripts/all-71189092.js.gz
Binary file not shown.
Binary file modified docs/v1/javascripts/all_nosearch-0f98dbdc.js.gz
Binary file not shown.
Binary file modified docs/v1/stylesheets/screen-d3a39341.css.gz
Binary file not shown.
43 changes: 28 additions & 15 deletions source/includes/_board-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const board = await wtClient.board.create({

client = WeTransfer::Client.new(api_key: 'YOUR PRIVATE API KEY GOES HERE')

board = client.create_board_and_upload_items(name: 'Kittens') do |builder|
board = client.create_board_and_upload_items(name: 'Little kittens') do |builder|
builder.add_file(
name: 'bobis.jpg',
io: File.open('/path/to/kitty.jpg', 'rb')
Expand Down Expand Up @@ -75,11 +75,15 @@ puts "The board can be viewed on #{board.url}"
}
```

<aside class="warning"><strong>Note:</strong> The <code>url</code> in the response is the URL you will use to access the board you create! It is not returned at the end of the upload flow, rather right now when you create the empty board.</aside>
<aside class="warning">**Note**: The `url` in the response is the URL you will use to access the board you created. It is not returned at the end of the upload flow, rather only right now when you create the (empty) board.</aside>

Later you'll want to interact with your board. Add files and links to it. In order to do that, make sure to note the value of the `id` property.

## Add links to a board

Once a board has been created you can add links like so:
A board can hold files *and* URLs. Lets have a look at how you can add URLs to your board. For that you need the `id` of the board you created earlier, unless your SDK will handle that for you.

Once a board has been created you can add links like below:

```shell
curl -i -X POST "https://dev.wetransfer.com/v2/boards/{board_id}/links" \
Expand Down Expand Up @@ -194,7 +198,7 @@ const fileItems = await apiClient.board.addFiles(board, [{
"name": "big-bobis.jpg",
"size": 195906,
"multipart": {
"id": "some.random-id--",
"id": "some random id",
"part_numbers": 1,
"chunk_size": 195906
},
Expand All @@ -203,17 +207,23 @@ const fileItems = await apiClient.board.addFiles(board, [{
]
```

The endpoint will return an object for each file you want to add to the board. Each file must be split into chunks, and uploaded to a pre-signed S3 URL, provided by the following endpoint.
The endpoint will return an object for each file you want to add to the board. The data returned is helpful in the next step when we want to request a place where we can upload our file.

The important parts in the response are the `id` of the file, the `id` of the multipart object, together with its `part_numbers`.

**Important**

Board chunks _must_ be 6 megabytes in size, except for the very last chunk, which can be smaller. Sending too much or too little data will result in a 400 Bad Request error when you finalise the file.
Board chunks _must_ be 6 megabytes (or more precisely 6291456 bytes) in size, except for the very last chunk, which can be smaller. Sending too much or too little data will result in a `400 Bad Request` error when you finalize the file. As with transfers: Do not let us down.

<h2 id="board-request-upload-url">Request upload URL</h2>

Now that you've informed us about the file(s) you want to upload, it is time to request upload URLs. Each chunk of the file has its own upload url.

<h3 class="call"><span>GET</span> /boards/{board_id}/files/{file_id}/upload-url/{part_number}/{multipart_upload_id}</h3>

To be able to upload a file, it must be split into chunks, and uploaded to different presigned URLs. This route can be used to fetch presigned upload URLS for each of a file's parts. These upload URLs are essentially limited access to a storage bucket hosted with Amazon. They are valid for an hour and must be re-requested if they expire.
To be able to upload a file, it must be split into chunks, and uploaded to different pre-signed URLs. This endpoint can be used to get pre-signed upload URLs for each of a file's parts. These upload URLs are essentially limited access to a storage bucket hosted with Amazon. They are valid for an hour and must be re-requested if they expire.

Use the fields from the previous response; now you need the `id` of the file, the `id` of the multipart, and you must request a upload-url for all of your `part_numbers`.

```shell
curl -i -X GET "https://dev.wetransfer.com/v2/boards/{board_id}/files/{file_id}/upload-url/{part_number}/{multipart_upload_id}" \
Expand Down Expand Up @@ -269,15 +279,15 @@ for (

```json
{
"url": "https://presigned-s3-put-url"
"url": "https://a-very-long-pre-signed-s3-put-url"
}
```

The Response Body contains the presigned S3 upload `url`.
The response body contains the pre-signed S3 upload `url`. You will use that in the next step, when you upload the contents.

##### 401 (Unauthorized)

If the requester tries to request an upload URL for a file that is not in one of the requester's boards, we will respond with 401 UNAUTHORIZED.
If you try to request an upload URL for a file that is not in one of your boards, the response will have a status code of 401 UNAUTHORIZED.

##### 400 (Bad request)

Expand All @@ -287,7 +297,7 @@ If a request is made for a part, but no `multipart_upload_id` is provided; we wi

<h3 id="board-upload-part" class="call"><span>PUT</span> {signed_url}</h3>

Please note: errors returned from S3 will be sent as XML, not JSON. If your response parser is expecting a JSON response it may throw an error here. Please see AWS' <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html" target="_blank">S3 documentation</a> for more details about specific responses.
You're communicating directly with Amazons' S3, not with our API. Please note: errors returned from S3 will be sent as XML, not JSON. If your response parser is expecting a JSON response it may throw an error here. Please see AWS' <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html" target="_blank">S3 documentation</a> for more details about specific responses.

```shell
curl -i -T "./path/to/big-bobis.jpg" "https://signed-s3-upload-url"
Expand Down Expand Up @@ -404,10 +414,10 @@ curl -i -X GET "https://dev.wetransfer.com/v2/boards/{board_id}" \
{
"id": "random-hash",
"name": "kittie.gif",
"size": 1024,
"size": 195906,
"multipart": {
"part_numbers": 1,
"chunk_size": 1024
"chunk_size": 195906
},
"type": "file"
},
Expand All @@ -425,8 +435,11 @@ curl -i -X GET "https://dev.wetransfer.com/v2/boards/{board_id}" \

##### 403 (Forbidden)

If the requester tries to request a board that is not in one of the requester's boards, we will respond with 403 FORBIDDEN.
If you try to request a board that is not yours, we will respond with 403 FORBIDDEN.

```json
{"success":false, "message":"This board does not belong to you"}
{
"success":false,
"message":"This board does not belong to you"
}
```
3 changes: 1 addition & 2 deletions source/includes/_sdks.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

## V2 and V1 Compatible SDKs

These SDKs are or soon will be compatible with V1 and V2 of the WeTransfer API. Feel free to file
issues or PRs to help them along! :)
These SDKs are or soon will be compatible with V1 and V2 of the WeTransfer API. Feel free to file issues or PRs to help them along! :)

<section class="sdks">
<article class="sdk sdk-node">
Expand Down
130 changes: 96 additions & 34 deletions source/includes/_transfer-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,29 @@ Transfers must be created with files. Once the transfer has been created and fin

When you create a transfer, you must include at least one file in the transfer create request.

Creating a transfer is to inform the API that you want to create a transfer (with at least one file), but you aren't sending the files already.

What you are sending is the `message`, a property that describes what this transfer is about, and a collection of file `name`s and their `size`. This allows the API to set up a place where your files can be uploaded to in a later state. Make sure the size of the file is accurate. Please don't lie to us; we will not be able to handle your files in a later stage...

```shell
curl -i -X POST "https://dev.wetransfer.com/v2/transfers" \
-H "Content-Type: application/json" \
-H "x-api-key: your_api_key" \
-H "Authorization: Bearer jwt_token" \
-d '{"message":"My very first transfer!","files":[
{"name":"big-bobis.jpg", "size":195906}, "name":"kitty.jpg", "size":369785]}'
-H "x-api-key: REPLACE_WITH_YOUR_API_KEY" \
-H "Authorization: Bearer REPLACE_WITH_YOUR_TOKEN" \
-d '
{
"message":"My very first transfer!",
"files":[
{
"name":"big-bobis.jpg",
"size":195906
},
{
"name":"kitty.jpg",
"size":369785
}
]
}'
```

```javascript
Expand Down Expand Up @@ -82,37 +98,44 @@ puts "The transfer can be viewed on #{transfer.url}"

```json
{
"id": "random-hash",
"message": "My very first transfer!",
"state": "uploading",
"files": [
"message" : "My very first transfer!",
"files" : [
{
"id": "random-hash",
"name": "big-bobis.jpg",
"size": 195906,
"multipart": {
"part_numbers": 1,
"chunk_size": 5242880
}
"multipart" : {
"part_numbers" : 1,
"chunk_size" : 195906
},
"size" : 195906,
"type" : "file",
"name" : "big-bobis.jpg",
"id" : "c964caf6c54343f3b6e9610cb4ac5ea220181019143517"
},
{
"id": "random-hash",
"name": "kitty.jpg",
"size": 369785,
"multipart": {
"part_numbers": 1,
"chunk_size": 5242880
}
"multipart" : {
"part_numbers" : 1,
"chunk_size" : 369785
},
"size" : 369785,
"type" : "file",
"id" : "e7f74773661f2be2bec90e6322864abd20181019143517",
"name" : "kitty.jpg"
}
]
],
"url" : null,
"id" : "32a6ef6003f1429be0cf1674dd8fbdef20181019143517",
"state" : "uploading"
}
```

Creates a new transfer with specified files.

## Request upload URL
## Request upload URLs

If you look at that response above, you see some pointers that are needed now. All files should be uploaded to a specific place. You just have to get the place from our API. To do that, you ask the API based on the `transfer.id`, each and every `file.id`, and for each part (based on the `file.multipart.part_numbers` property).

To be able to upload a file, it must be split into parts and then each part will be uploaded to pre-signed AWS S3 URLs.

To be able to upload a file, it must be split into parts and then each part will be uploaded to presigned AWS S3 URLs. This route can be used to fetch presigned upload URLS for each of a file's parts. These upload URLs are essentially limited access to a storage bucket hosted with Amazon. NB: They are valid for an <em>hour</em> and must be re-requested if they expire.
This endpoint can be used to get pre-signed upload URLS for each of a file's parts. These upload URLs are essentially limited access to a storage bucket hosted with Amazon. NOTE: They are valid for an **hour** and must be re-requested if they expire.

```shell
curl -i -X GET "https://dev.wetransfer.com/v2/transfers/{transfer_id}/files/{file_id}/upload-url/{part_number}" \
Expand Down Expand Up @@ -176,24 +199,46 @@ Transfer chunks must be 5 megabytes in size, except for the very last chunk, whi
}
```

The Response Body contains the presigned S3 upload `url`.
The Response Body contains the pre-signed S3 upload `url`.

##### 404 (Not found)

If the requester tries to request an upload URL for a file that is not in one of the requester's transfers, we will respond with 404 Not found.
If you try to request an upload URL for a file that is not in the transfers, the API will respond with 404 Not found.

```json
{
"success" : false,
"message" : "Couldn't find FileObject"
}
```

##### 417 (Expectation Failed)

If you request to upload part `0`, our API will tell you that our parts are numbered for humans; we start counting at part 1:

```json
{
"success" : false,
"message" : "Chunk numbers are 1-based"
}
```

<h2 id="transfer-file-upload">File Upload</h2>

<h3 id="transfer-upload-part" class="call"><span>PUT</span> {signed_url}</h3>

Time to actually upload (chunks of) your file. With the pre-signed-upload-url you retrieved in the previous step, you can start uploading!

You will interact directly with Amazon S3. As such, we have no control over the messages sent by S3.

Important: errors returned from S3 will be sent as XML, not JSON. If your response parser is expecting a JSON response it may throw an error here. Please see AWS' <a href="https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html" target="_blank">S3 documentation</a> for more details about specific responses.

```shell
curl -i -T "./path/to/big-bobis.jpg" "https://signed-s3-upload-url"
```

```javascript
// Use your favourite JS
// Use your favorite JS
const fs = require('fs');

const file = transfer.files[0];
Expand Down Expand Up @@ -230,7 +275,9 @@ for (

<h2 id="transfer-complete-file-upload">Complete a file upload</h2>

Finalize a file. Once all the parts have been uploaded succesfully, you use this endpoint to tell the system that it can start splicing the parts together to form one whole file.
In the previous step, you've uploaded your file (potentially in parts) directly to S3. The WeTransfer API has no idea when that is complete. This call informs your transfer object that all the uploading for your file is done.

Again, to inform the API about this event, you need both the transfer id and the file id. Not only that, you currently also have to inform this endpoint on the amount of part numbers.

```shell
curl -i -X PUT "https://dev.wetransfer.com/v2/transfers/{transfer_id}/files/{file_id}/upload-complete" \
Expand Down Expand Up @@ -280,9 +327,22 @@ await wtClient.transfer.completeFileUpload(transfer, file);
}
```

##### 417

If you try to finalise a file, but didn't actually upload all chunks it will respond with something like this:

```json
{
"success": false,
"message": "Chunks 1 are still missing"
}
```

<h2 id="finalize-a-transfer">Finalize a transfer</h2>

Finalize the whole transfer. Once all the parts have been uploaded and finalized, you use this endpoint to tell the system that everything has been completely uploaded.
After all files are uploaded and finalized, you can close the transfer for modification, and make it available for download.

You do that by calling this endpoint. It informs the API that everything has been completely uploaded.

```shell
curl -i -X PUT "https://dev.wetransfer.com/v2/transfers/{transfer_id}/finalize" \
Expand Down Expand Up @@ -322,12 +382,14 @@ console.log(finalTransfer.url);

##### 200 (OK)

If all went well, the API sends you a lot of data. One of them being the `url`. That is the thing you will use to access the files in a browser.

```json
{
"id": "random-hash",
"state": "processing",
"message": "Little kittens",
"url": "https://we.tl/t-smaller-random-hash",
"message": "My first transfer!",
"url": "https://we.tl/t-12344657",
"files": [
{
"id": "random-hash",
Expand All @@ -343,7 +405,7 @@ console.log(finalTransfer.url);
```

<aside class="notice">
The <code>url</code> field is where you get the link you will need to access the transfer!
The `url` field is where you get the link you will need to access the transfer!
</aside>

##### 400 (Bad Request)
Expand All @@ -352,4 +414,4 @@ This is returned if the transfer can no longer be written to, or is it ready to

##### 403 (Unauthorized)

When you try to access something you don't have access to.
When you try to finalize a transfer you don't have access to.
2 changes: 1 addition & 1 deletion source/index.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ You can use our API to share files, links and love all over the world.

## Our APIs

Depending on what you want to make we have two different APIs: transfers and boards.
Depending on what you want to make we have two main tastes: **transfers** and **boards**.

<div class="two-col">
<div class="col">
Expand Down