Introduction
Welcome to the Algorithmia API documentation! You can use the API to access any algorithm in the marketplace.
We have clients & libraries in multiple languages. We encourage you to click on the different language tabs at the top of the right-side pane to see code samples in your language of choice.
This documentation will serve as a reference as you start to integrate the Algorithmia API into your code.
If this is your first time trying Algorithmia, you might find it useful to start with our Getting Started guide, which can be found alongside many other resources in the Algorithmia Developer Center.
Authentication
API Keys
To authorize, use this code:
# With shell, you can just pass the correct header with each request
curl "api_endpoint_here" -H 'Authorization: Simple YOUR_API_KEY'
$ algo auth
Configuring authentication for 'default' profile
Enter API Key (prefixed with 'sim'): YOUR_API_KEY
Profile is ready to use. Test with 'algo ls'
import Algorithmia
client = Algorithmia.client('YOUR_API_KEY')
library(algorithmia)
client <- Algorithmia$client('YOUR_API_KEY')
require 'algorithmia'
client = Algorithmia.client('YOUR_API_KEY')
import com.algorithmia.*;
import com.algorithmia.algo.*;
AlgorithmiaClient client = Algorithmia.client("YOUR_API_KEY");
import com.algorithmia._
import com.algorithmia.algo._
val client = Algorithmia.client("YOUR_API_KEY")
extern crate algorithmia
use algorithmia::*;
use algorithmia::algo::*;
let client = Algorithmia::client("YOUR_API_KEY");
// include the algorithmia.js library
// https://algorithmia.com/v1/clients/js/algorithmia-0.2.0.js
var client = Algorithmia.client('YOUR_API_KEY');
var client = Algorithmia.client('YOUR_API_KEY');
Make sure to replace
YOUR_API_KEYwith your API key.
API requests are authenticated by a key which can be found and managed from your user profile. With every call to the API, the user must be authenticated. The API has a simple means to do this by passing in your key as an HTTP “Authorization” header with the request.
When you signed up for Algorithmia, a ‘default-key’ was generated for your convenience. This is the key that is used throughout the example code within algorithm pages. For these examples to work correctly, this default key must exist with all the permissions, otherwise the usage examples may result in a 401 Unauthorized error.
Key Restrictions
Algorithmia provides you with fine-grained controls for restricting what API calls can be made with a specific key from the Credentials section of your user profile.
You can create or modify any key to include any or all of the following restrictions:
- Algorithm access: a white list of specific algorithms that can be called
- Native Clients: allow the key to be used in any request that didn’t originate from a web browser (non-CORS)
- Web Browser: allows the key to be used for cross-origin requests (CORS). This is required for any key that you embed on your site. If you intend to embed this key in your site, we recommend that you disallow data access and white list only the algorithms that your site calls.
- Restrict referrer hostname: only allow cross-origin requests from a specific domain. This is recommended when embedding your API key in your site.
- Data access: control the Data API read/write access for a key. Note that this restriction does not prevent an algorithm from using the Data API. See the Data API documentation for details on further managing permissions of your data.
API Specification
The Algorithmia API gives developers the ability to build applications that interact with and use all the features of Algorithmia in an automated fashion. Tasks can be generated, work can be ordered, and your application can be notified as data is processed by Algorithmia.
Requests to the API must be formatted in JSON. We follow the JSON-RPC 2.0 spec.
A properly formatted request will always return the HTTP status code 200 OK; with either a result field (which may be null in some cases) for successes or an error field to indicate failure.
The size limit for a request is 10MiB. Check out the Data API for options on how to process larger files.
Call an Algorithm
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-d 'YOUR_NAME' -H 'Content-Type: text/plain' \
https://api.algorithmia.com/v1/algo/demo/Hello/0.1.1
$ algo run -d 'YOUR_NAME' demo/Hello/0.1.1
Hello YOUR_NAME
import Algorithmia
input = "YOUR_NAME"
client = Algorithmia.client('YOUR_API_KEY')
# Pass in the unique algoUrl path found on each algorithm description page.
algo = client.algo('demo/Hello/0.1.1')
# Calls an algorithm with the input provided.
result = algo.pipe(input)
# If you are using the 1.0+ client you can access both the output and the metadata.
print result.result # Hello YOUR_NAME
print result.metadata # Metadata(content_type='text',duration=0.0002127)
# If you are using 0.9.x you can only get the algorithm output
print result # Hello YOUR_NAME
# There are many other features missing in 0.9.x, to upgrade see the github docs.
library(algorithmia)
input <- "YOUR_NAME"
client <- Algorithmia$client('YOUR_API_KEY')
algo <- client$algo('demo/Hello/0.1.1')
result <- algo$pipe(input)$result
print(result)
require 'algorithmia'
client = Algorithmia.client('YOUR_API_KEY')
algo = client.algo('demo/Hello/0.1.1')
response = algo.pipe('YOUR_NAME')
puts response.result
import com.algorithmia.*;
import com.algorithmia.algo.*;
String input = "\"YOUR_NAME\"";
AlgorithmiaClient client = Algorithmia.client("YOUR_API_KEY");
Algorithm algo = client.algo("algo://demo/Hello/0.1.1");
AlgoResponse result = algo.pipeJson(input);
System.out.println(result.asJsonString());
import com.algorithmia._
import com.algorithmia.algo._
val input = "YOUR_NAME"
val client = Algorithmia.client("YOUR_API_KEY")
val algo = client.algo("algo://demo/Hello/0.1.1")
val result = algo.pipeJson(input)
System.out.println(result.asJsonString)
use algorithmia::*;
use algorithmia::algo::*;
let input = "YOUR_NAME";
let client = Algorithmia::client("YOUR_API_KEY");
let algo = client.algo("algo://demo/Hello/0.1.1");
// include the algorithmia.js library
// https://algorithmia.com/v1/clients/js/algorithmia-0.2.0.js
var input = "YOUR_NAME";
Algorithmia.client("YOUR_API_KEY");
client.algo("algo://demo/Hello/0.1.1")
.pipe(input)
.then(function(output) {
console.log(output);
});
var algorithmia = require("algorithmia");
var input = "YOUR_NAME";
var client = algorithmia.client("YOUR_API_KEY");
client.algo("algo://demo/Hello/0.1.1")
.pipe(input)
.then(function(response) {
console.log(response.get());
});
Make sure to replace
YOUR_NAMEwith your name &YOUR_API_KEYwith your API key.
For each algorithm on the marketplace, you’ll find an owner (the user who created the algorithm), an algorithm name, and a version number. Algorithms are called using this HTTP endpoint:
POST https://api.algorithmia.com/v1/algo/:owner/:algoname/[:version]
Specifying a version is recommended, but optional. If not specified, the latest publicly published version will be used. When explicitly specifying a version, the following following formats are accepted:
| Version | Description |
|---|---|
1.1.1 |
Fully specified version |
1.2.* |
Specified to the minor level. Will resolve to the latest publicly published version with a minor version of 1.2 |
1.* |
Specified to a major version. Will resolve to the latest publicly published version with major version 1 |
Input/Output
Text Input/Output
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-d 'HAL 9000' -H 'Content-Type: text/plain' \
https://api.algorithmia.com/v1/algo/demo/Hello/0.1.1
-> {
"result":"Hello HAL 9000",
"metadata":{"content_type":"text","duration":0.034232617}
}
$ algo run demo/Hello/0.1.1 -d 'HAL 9000'
Hello HAL 9000
algo = client.algo('demo/Hello/0.1.1')
print algo.pipe("HAL 9000").result
# -> Hello HAL 9000
algo <- client$algo('demo/Hello/0.1.1')
print(algo$pipe("HAL 9000")$result)
# -> Hello HAL 9000
algo = client.algo('demo/Hello/0.1.1')
puts algo.pipe('HAL 9000').result
# -> Hello HAL 900
Algorithm algo = client.algo("algo://demo/Hello/0.1.1");
AlgoResponse result = algo.pipe("HAL 9000");
System.out.println(result.asString());
// -> Hello HAL 9000
val algo = client.algo("algo://demo/Hello/0.1.1")
val result = algo.pipe("HAL 9000")
System.out.println(result.asString)
// -> Hello HAL 9000
let algo = client.algo("algo://demo/Hello/0.1.1");
let response = algo.pipe("HAL 9000").unwrap();
println!("{}", response.as_string().unwrap());
client.algo("algo://demo/Hello/0.1.1")
.pipe("HAL 9000")
.then(function(output) {
console.log(output.result);
});
// -> Hello HAL 9000
client.algo("algo://demo/Hello/0.1.1")
.pipe("HAL 9000")
.then(function(response) {
console.log(response.get());
});
// -> Hello HAL 9000
JSON Input/Output (including serialized objects/arrays)
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '["transformer", "terraforms", "retransform"]' \
https://api.algorithmia.com/v1/algo/WebPredict/ListAnagrams/0.1
-> {
"result": ["transformer","retransform"],
"metadata":{"content_type":"json","duration":0.039351226}
}
# -d automatically detects if input is valid JSON
$ algo run WebPredict/ListAnagrams/0.1 \
-d '["transformer", "terraforms", "retransform"]'
["transformer","retransform"]
algo = client.algo('WebPredict/ListAnagrams/0.1.0')
result = algo.pipe(["transformer", "terraforms", "retransform"]).result
# -> ["transformer","retransform"]
algo <- client$algo('WebPredict/ListAnagrams/0.1.0')
result <- algo$pipe(["transformer", "terraforms", "retransform"])$result
# Returns a list in R
[[1]]
[1] "transformer"
[[2]]
[1] "retransform"
algo = client.algo('WebPredict/ListAnagrams/0.1.0')
result = algo.pipe(["transformer", "terraforms", "retransform"]).result
# -> ["transformer","retransform"]
Algorithm algo = client.algo("algo://WebPredict/ListAnagrams/0.1.0");
List<String> words = Arrays.asList(("transformer", "terraforms", "retransform");
AlgoResponse result = algo.pipe(words);
// WebPredict/ListAnagrams returns an array of strings, so cast the result:
List<String> anagrams = result.as(new TypeToken<List<String>>(){});
// -> List("transformer", "retransform")
// Or using raw JSON
String jsonWords = "[\"transformer\", \"terraforms\", \"retransform\"]"
AlgoResponse result2 = algo.pipeJson(jsonWords);
String anagrams = result2.asJsonString();
// -> "[\"transformer\", \"retransform\"]"
val algo = client.algo("algo://WebPredict/ListAnagrams/0.1.0")
val result = algo.pipe(List("transformer", "terraforms", "retransform"))
// WebPredict/ListAnagrams returns an array of strings, so cast the result:
val anagrams = result.as(new TypeToken<List<String>>(){})
// -> List("transformer", "retransform")
// Or using raw JSON
val result2 = algo.pipeJson("""["transformer", "terraforms", "retransform"]""")
String anagrams = result.asJsonString();
// -> "[\"transformer\", \"retransform\"]"
let algo = client.algo("algo://WebPredict/ListAnagrams/0.1.0");
let response = algo.pipe(vec!["transformer", "terraforms", "retransform"]).unwrap();
let output: Vec<String> = response.decode().unwrap();
// -> ["transformer", "retransform"] as Vec<String>
// Or working with raw JSON
let response2 = algo.pipe_json(r#"["transformer", "terraforms", "retransform"]"#).unwrap();
let output = response2.as_json().unwrap().to_string();
// -> "[\"transformer\", \"retransform\"]"
client.algo("algo://WebPredict/ListAnagrams/0.1.0")
.pipe(["transformer", "terraforms", "retransform"])
.then(function(output) {
console.log(output.result);
// -> ["transformer","retransform"]
});
// Or using raw JSON
client.algo("algo://WebPredict/ListAnagrams/0.1.0")
.pipeJson('["transformer", "terraforms", "retransform"]')
.then(function(output) {
console.log(output.result);
// -> ["transformer","retransform"]
});
client.algo("algo://WebPredict/ListAnagrams/0.1.0")
.pipe(["transformer", "terraforms", "retransform"])
.then(function(response) {
console.log(response.get());
// -> ["transformer","retransform"]
});
// Or using raw JSON
client.algo("algo://WebPredict/ListAnagrams/0.1.0")
.pipeJson('["transformer", "terraforms", "retransform"]')
.then(function(response) {
console.log(response.get());
// -> ["transformer","retransform"]
});
Binary Input/Output
# Save output to bender_thumb.png since consoles don't handle printing binary well
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-H 'Content-Type: application/octet-stream' \
--data-binary @bender.jpg \
-o bender_thumb.png \
https://api.algorithmia.com/v1/algo/opencv/SmartThumbnail/0.1
# -D reads input from a file
# -o saves output to a file since consoles don't print binary well
$ algo run opencv/SmartThumbnail/0.1 -D bender.jpg -o bender_thumb.png
Completed in 1.1 seconds
input = bytearray(open("/path/to/bender.png", "rb").read())
result = client.algo("opencv/SmartThumbnail/0.1").pipe(input).result
# -> [binary byte sequence]
algo <- client$algo("opencv/SmartThumbnail/0.1")
response <- algo$pipe(input)$result
# -> [raw vector]
input = File.binread("/path/to/bender.png")
result = client.algo("opencv/SmartThumbnail/0.1").pipe(input).result
# -> [ASCII-8BIT string of binary data]
byte[] input = Files.readAllBytes(new File("/path/to/bender.jpg").toPath());
AlgoResponse result = client.algo("opencv/SmartThumbnail/0.1").pipe(input);
byte[] buffer = result.as(new TypeToken<byte[]>(){});
// -> [byte array]
let input = Files.readAllBytes(new File("/path/to/bender.jpg").toPath())
let result = client.algo("opencv/SmartThumbnail/0.1").pipe(input)
let buffer = result.as(new TypeToken<byte[]>(){})
// -> [byte array]
let mut input = Vec::new();
File::open("/path/to/bender.jpg").read_to_end(&mut input);
let response = client.algo("opencv/SmartThumbnail/0.1").pipe(&input).unwrap();
let output = response.as_bytes().unwrap();
// -> Vec<u8>
/*
Support for binary I/O in the javascript client is planned.
Contact us if you need this feature, and we'll prioritize it right away:
https://algorithmia.com/contact
Note: The NodeJS client does currently support binary I/O.
*/
var buffer = fs.readFileSync("/path/to/bender.jpg");
client.algo("opencv/SmartThumbnail")
.pipe(buffer)
.then(function(response) {
var buffer = response.get();
// -> Buffer(...)
});
Algorithmia supports calling algorithms that use any combination of text, JSON, or binary as their input and output.
Each client SDK provides idiomatic abstractions for calling algorithms using common native types and automatic serializization and deserialization where reasonable. See the code samples to the right for examples in the language of your choice.
HTTP input specification
To specify input when making a raw HTTP request, the body of the request is the input to the algorithm you are calling.
To specify the input type, set the Content-Type header accordingly. These are
| Content-Type | Description |
|---|---|
application/json |
body specifies JSON input data (UTF-8 encoded) |
application/text |
body specifies text input data (UTF-8 encoded) |
application/octet-stream |
body specifies binary input data (raw bytes) |
HTTP output specification
The metadata.content_type specifies which type of encoding the result element is in.
| Content-Type | Description |
|---|---|
| void | The result element is null |
| text | The result element is a JSON string using UTF-8 encoding |
| json | The result element is any valid JSON type |
| binary | The result element is a Base64 encoded binary data in a JSON String |
Query Parameters
Query Parameters
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-d 'HAL 9000' -H 'Content-Type: text/plain' \
https://api.algorithmia.com/v1/algo/demo/Hello/0.1.1?timeout=10
# use --timeout to set the call timeout
$ algo run demo/Hello/0.1.1 -d 'HAL 9000' --timeout 10
# use --debug to print STDOUT if available
$ algo run demo/Hello/0.1.1 -d 'HAL 9000' --debug
algo = client.algo('demo/Hello/0.1.1').set_options(timeout=10, stdout=True)
result = algo.pipe("HAL 9000")
from Algorithmia.algorithm import OutputType
algo = client.algo('demo/Hello/0.1.1').set_options(output=OutputType.raw)
algo <- client$algo('util/echo')
algo$setOptions(timeout=40, stdout=FALSE)
result <- algo$pipe('HAL 9000')$result
algo = client.algo('demo/Hello/0.1.1').set_timeout(10).enable_stdout
result = algo.pipe('HAL 9000').result
Algorithm algo = client.algo("algo://demo/Hello/0.1.1?timeout=10");
AlgoResponse result = algo.pipe("HAL 9000");
val algo = client.algo("algo://demo/Hello/0.1.1?timeout=10")
val result = algo.pipe(input)
let mut algo = client.algo("algo://demo/Hello/0.1.1");
let algo = algo.timeout(10).enable_stdout();
let response = algo.pipe(input).unwrap();
if let Some(ref stdout) = response.metadata.stdout {
println!("{}", stdout);
}
client.algo("algo://demo/Hello/0.1.1?timeout=10")
.pipe("HAL 9000")
.then(function(output) {
console.log(output);
});
client.algo("algo://demo/Hello/0.1.1?timeout=10")
.pipe("HAL 9000")
.then(function(output) {
console.log(output);
});
The API also provides the following configurable parameters when calling an algorithm:
| Parameter | Description |
|---|---|
| timeout | number: Specifies a timeout for the call in seconds. default=300 (5min), max=3000 (50min) |
| stdout | boolean: Indicates algorithm stdout should be returned in the response metadata (ignored unless you are the algorithm owner) |
| output | raw |
timeout={seconds}- Specifies a timeout for the call in seconds
- The default timeout is 5 minutes
- The maximum configurable timeout is 50 minutes
stdout=true- Returns the stdout that the algorithm produced during the call
- Will only display if the algorithm author initiates the call
output=raw- Returns the result of the algorithm call without the JSON-RPC wrapper
- If the algorithm returned an error then an HTTP 400 status code will be used
output=void- Returns immediately and does not wait for the algorithm to run
- The result of the algorithm will not be accessible; this is useful in some cases where an algorithm outputs to a
data://file with a long running time (see The Data API for more information)
Error Handling
Error Handling
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-d '[]' -H 'Content-Type: application/json' \
https://api.algorithmia.com/v1/algo/demo/Hello/0.1.1
-> {
"error":{
"message":"apply() functions do not match input data",
"stacktrace":"apply() functions do not match input data"
},
"metadata":{"duration":0.046542354}}
}
$ algo run demo/Hello/0.1.1 -d '[]'
API error: apply() functions do not match input data
apply() functions do not match input data
algo = client.algo('demo/Hello/0.1.1')
print algo.pipe([]).error.message
# -> API error: apply() functions do not match input data
algo <- client$algo('demo/Hello/0.1.1')
algo$pipe(list())$error$message
# -> API error: apply() functions do not match input data
algo = client.algo('demo/Hello/0.1.1')
puts algo.pipe([]).error.message
# -> API error: apply() functions do not match input data
Algorithm algo = client.algo("algo://demo/Hello/0.1.1");
AlgoResponse result = algo.pipe([]);
try {
result.asString();
} catch (AlgorithmException ex) {
System.out.println(ex.getMessage());
}
// -> API error: apply() functions do not match input data
val algo = client.algo("algo://demo/Hello/0.1.1")
val result = algo.pipe("HAL 9000")
try {
result.asString();
} catch {
case ex: AlgorithmException => System.out.println(ex.getMessage)
}
// -> API error: apply() functions do not match input data
let algo = client.algo("algo://demo/Hello/0.1.1");
match algo.pipe(&[]) {
Ok(response) => { /* success */ },
Err(err) => println!("error calling demo/Hello: {}", err),
}
// -> error calling demo/Hello: apply() functions do not match input data
client.algo("algo://demo/Hello/0.1.1")
.pipe("HAL 9000")
.then(function(output) {
if(output.error) {
console.log(output.error.message);
}
});
// -> API error: apply() functions do not match input data
client.algo("algo://demo/Hello/0.1.1")
.pipe("HAL 9000")
.then(function(response) {
if(response.error) {
console.log(response.error.message);
}
});
// -> API error: apply() functions do not match input data
If an error occurs, the response will contain the following fields:
| Field | Description |
|---|---|
| error.message | The error message |
| error.stacktrace | (Optional) a stacktrace if the error occurred within the algorithm (only if caller has access to algorithm source) |
Each client provides a language-specific solution for error handling. The examples on the right
come from calling an algorithm that expects text input in it’s implementation of the apply entrypoint,
but instead receives a JSON array as input.
Data API Specification
/*
The Javascript client does not currently have support for the Data API.
Contact us if you need this feature and we'll prioritize it right away:
https://algorithmia.com/contact
Note: The NodeJS client does currently support the Data API.
*/
The Algorithmia Data API provides a way of getting data into and out of algorithms with support for Algorithmia Hosted Data as well as working directly with data in your Dropbox account or Amazon S3 buckets. For an introduction to working with data from these different data sources, see the data portal guides for Algorithm Developers or for Application Developers.
Data URI
A Data URI uniquely identifies files and directories. A Data URI is composed of a protocol and a path (e.g. data://.my/photos).
Each connected data source has has a unique protocol. Supported protocols include:
| Protocol | Description |
|---|---|
data:// |
Algorithmia hosted data |
dropbox:// |
Dropbox default connected account |
s3:// |
Amazon S3 default connected account |
Additionally, if you connect multiple accounts from the same source,
they can be uniquely identified by their label, e.g. dropbox+mylabel://.
The path part of a Data URI is understood in the context of each source:
| URI | Description |
|---|---|
data://.my/foo |
The foo collection of your Algorithmia hosted data |
dropbox://foo |
The foo file or directory in the root of your default Dropbox connected account |
s3://foo |
The foo bucket of your S3 account |
The remainder of this documentation provides the specification for working with directories and files regardless of what data source they come from.
Directories
Directories are a collection of files or other directories.
Listing a directory
Listing a directory:
# List top-level user directory
curl -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my
-> {
"folders": [
{ "name": "robots" },
{ "name": "cats" }
]
}
# List a directory with ACLs
curl -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my/robots?acl=true
-> {
"files": [
{
"filename": "R2-D2.txt",
"last_modified": "2016-01-06T00:52:34.000Z"
"size": 48
},
{
"filename": "T-800.txt",
"last_modified": "2016-01-06T00:52:34.000Z"
"size": 36
}
],
"acl": {
"read": [ "algo://.my/*" ]
},
"marker": "12-abcdefgj9ao72LHhjglh3AcRtCuf7T1FeSoZTA1gycqRHaDrdp254LV9S1LjKgQZ"
}
$ algo ls data://.my
robots cats
$ algo ls -l data://.my/robots
2016-01-06 00:52:34 48 R2-D2.txt
2016-01-06 00:52:34 36 T-800.txt
# List top level directories
import Algorithmia
client = Algorithmia.client()
# The .dir() method takes a Data URI path and returns an Algorithmia.datadirectory.DataDirectory object for the child directory.
client.dir("data://.my")
# Check if a specific directory exists
client.dir("data://.my/robots").exists()
# The .dirs() method returns a generator object of all the child directories.
for dir in client.dir("data://.my").dirs():
# The .url is a convenience field that holds "/v1/data/" + dir.path
# The .path is the path to the directory
print "Directory " + dir.path + " at URL " + dir.url
# List files in the 'robots' directory
dir = client.dir("data://.my/robots")
# The .files() method returns a generator object of all the files in directory
for file in dir.files():
print "File " + file.path + " at URL " + file.url + " last modified " + file.last_modified
# List top level directories
dir <- client$dir("data://.my/")
dirs <- dir$dirs()
while (dirs$hasNext()) {
d <- try(dirs$getNext())
print(paste(d$dataDirectoryUrl, d$dataDirectoryPath))
}
# List files in the 'robots' directory
robots = client$dir("data://.my/robots")
while (robots$hasNext()) {
d <- try(robots$getNext())
print(paste(d$dataDirectoryUrl, d$dataDirectoryPath))
}
# List top level directories
client.dir("data://.my").each_dir do |dir|
puts "Directory " + dir.data_uri
end
# List files in the 'robots' directory
client.dir("data://.my/robots").each_file do |file|
puts "File " + file.data_uri
end
import com.algorithmia.*;
import com.algorithmia.data.*;
// List top level directories
DataDirectory myRoot = client.dir("data://.my");
for(DataDirectory dir : myRoot.dirs()) {
System.out.println("Directory " + dir.toString() + " at URL " + dir.url());
}
// List files in the 'robots' directory
DataDirectory robots = client.dir("data://.my/robots");
for(DataFile file : robots.files()) {
System.out.println("File " + file.toString() + " at URL: " + file.url());
}
import com.algorithmia._
import com.algorithmia.data._
// List top level directories
val myRoot = client.dir("data://.my")
for(dir <- myRoot.getDirIter) {
println(s"Directory ${dir.toString} at URL: ${dir.url}")
}
// List files in the 'robots' directory
val robots = client.dir("data://.my/robots")
for(file <- robots.getFileIter) {
println(s"File ${file.toString} at URL: ${file.url}")
}
use algorithmia::*;
use algorithmia::data::*;
let my_robots = client.dir("data://.my/robots");
for entry in my_robots.list() {
match entry {
Ok(DirEntry::Dir(dir)) => println!("Directory {}", dir.to_data_uri()),
Ok(DirEntry::File(file)) => println!("File {}", file.to_data_uri()),
Err(err) => println!("Error listing my robots: {}", err),
}
}
// List top level directories
client.dir("data://.my").forEachDir(function(err, dir) {
if(err) {
return console.log("Error: " + JSON.stringify(err));
}
console.log(dir.data_path);
}).then(function() {
console.log("Finished listing directory");
});
// List files in the 'robots' directory
client.dir("data://.my/robots").forEachFile(function(err, file) {
if(err) {
return console.log("Error: " + JSON.stringify(err));
}
console.log(file.data_path);
}).then(function() {
console.log("Finished listing directory");
});
List the contents of a directory with this HTTP endpoint:
GET https://api.algorithmia.com/api/v1/connector/:connector/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Query Parameters
| Parameters | Description |
|---|---|
| marker | Indicates the page of results to return. Only valid when using markers previously returned by this API. If this parameter is omited then the first page is returned |
| acl | Include the directory ACL in the response. (Default = false) |
HTTP Response
The response JSON contains the following attributes:
| Attribute | Description |
|---|---|
| folders | [Optional] array of subdirectories |
| files | [Optional] array of files in directory. last_modified is an ISO-8601 timestamp and size is measured in bytes |
| marker | [Optional] string that indicates there are more files or folders within this directory that can be queried for using the marker query parameter |
| acl.read | [Optional] array of ACL strings defining who has read permissions to this directory. Explanation of ACL strings provided below. |
The API is limited to returning 1000 folders or files at a time, so listing all contents of a directory may require multiple paginated requests.
ACL Strings:
user://*: Readable by anyone (public)algo://.my/*: Readable by your algorithms (default)- Fully private is represented as an empty list
- No other ACL strings are currently supported
Response Headers:
X-Data-Type: directory
Creating a directory
Creating a directory:
# Create a directory named 'robots'
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"name": "robots"}' \
https://api.algorithmia.com/v1/connector/data/.my
# Empty 200 response on success
# Create a publicly accessible directory named 'public_robots'
curl -X POST -H 'Authorization: Simple YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"name": "public_robots", "acl": {"read": ["user://*"]}}' \
https://api.algorithmia.com/v1/connector/data/.my
# Empty 200 response on success
$ algo mkdir data://.my/robots
Created directory: data://.my/robots
robots = client.dir("data://.my/robots")
robots.create()
# You can also create a directory with different permissions
from Algorithmia.acl import ReadAcl
# Supports: ReadAcl.public, ReadAcl.private, ReadAcl.my_algos
robots.create(ReadAcl.public)
robots <- client$dir("data://.my/robots")
robots$create()
# You can also create a directory with different permissions
# Supports: ReadAcl.PUBLIC, ReadAcl.PRIVATE, ReadAcl.MY_ALGORITHMS
robots$create(ReadAcl.PUBLIC)
robots = client.dir("data://.my/robots")
robots.create
DataDirectory robots = client.dir("data://.my/robots");
robots.create();
val robots = client.dir("data://.my/robots")
robots.create()
let robots = client.dir("data://.my/robots");
robots.create(DataAcl::default())
var robots = client.dir("data://.my/robots");
robots.create(function(response) {
if(response.error) {
return console.log("Failed to create dir: " + response.error.message);
}
console.log("Created directory: " + robots.data_path);
});
To create a directory through the Algorithmia Data API, use the following endpoint:
POST https://api.algorithmia.com/v1/connector/:connector/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathrefers to the path of the existing parent directory of the directory that should be created.
Input
Input is JSON and requires the header: Content-Type: application/json
| Attribute | Description |
|---|---|
| name | Name of the directory to create |
| acl | [Optional] JSON object specifying permissions of the directory |
ACL Attribute:
Permission for a directory are determined by setting acl.read to an array of ACL strings:
user://*: Readable by anyone (public)algo://.my/*: Readable by your algorithms (default)- Fully private is represented as an empty list
- No other ACL strings are currently supported
Example: "acl": {"read": []} implies the directory is fully private
Response:
Empty 200 response on success
Updating a directory
Updating a directory:
curl -X PATCH -H 'Authorization: Simple YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"acl": {"read": ["user://*"]}}' \
https://api.algorithmia.com/v1/connector/data/.my
# Empty 200 response on success
from Algorithmia.acl import ReadAcl, AclType
robots = client.dir("data://.my/robots")
robots.create()
print robots.get_permissions().read_acl == AclType.my_algos # True
# Supports: ReadAcl.public, ReadAcl.private, ReadAcl.my_algos
robots.update_permissions(ReadAcl.private) # True if update succeeded
robots <- client$dir("data://.my/robots")
# Create a directory with public permissions
robots$create(ReadAcl.PUBLIC)
acl <- robots$getPermissions() # Acl object
acl$read_acl # Returns Permission Type, "PUBLIC" if update succeeded.
# Supports: ReadAcl.PUBLIC, ReadAcl.PRIVATE, and ReadAcl.MY_ALGORITHMS.
robots$updatePermissions(ReadAcl.PRIVATE)
acl$read_acl # Returns Permission Type, "PRIVATE" if update succeeded.
DataDirectory robots = client.dir("data://.my/robots");
// Create the directory as private
robots.create(DataAcl.PRIVATE);
// Supports: DataAcl.PUBLIC, DataAcl.PRIVATE, DataAcl.My_ALGOS
robots.updatePermissions(DataAcl.PUBLIC);
// Check a directory's permissions
if (robots.getPermissions().getReadPermissions() == DataAclType.PRIVATE) {
System.out.println("fooLimited is private");
}
To update a directory, use the following API:
PATCH https://api.algorithmia.com/v1/connector/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Input:
Input is JSON and requires the header: Content-Type: application/json
| Attribute | Description |
|---|---|
| acl | [Optional] JSON object specifying permissions of the directory |
ACL Attribute:
Permission for a directory are determined by setting acl.read to an array of ACL strings:
user://*: Readable by anyone (public)algo://.my/*: Readable by your algorithms (default)- Fully private is represented as an empty list
- No other ACL strings are currently supported
Example: "acl": {"read": []} implies the directory is fully private
Output:
Empty 200 response on success
Deleting a directory
Deleting a directory
# Delete the empty directory data://.my/public_robots
curl -X DELETE -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my/public_robots
-> { "result": { "deleted": 0 }}
# Force delete the directory data://.my/robots even if it contains files
curl -X DELETE -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my/robots?force=true
-> { "result": { "deleted": 25 }}
$ algo rmdir data://.my/public_robots
Deleted directory: data://.my/public_robots
$ algo rmdir -f data://.my/robots
Deleted directory: data://.my/robots
robots = client.dir("data://.my/robots")
if robots.exists():
robots.delete()
robots <- client$dir("data://.my/robots")
if (robots$exists()){
robots$delete()
}
robots = client.dir("data://.my/robots")
robots.delete
# to force deletion even if dir contains file, use:
# robots.delete(true)
DataDirectory robots = client.dir("data://.my/robots");
robots.delete(false);
// use `true` to force deletion even if dir contains files
val robots = client.dir("data://.my/robots")
robots.delete(false)
// use `true` to force deletion even if dir contains files
let robots = client.dir("data://.my/robots");
robots.delete(false);
// use `true` to force deletion even if dir contains files
var robots = client.dir("data://.my/robots");
robots.delete(false, function(response) {
if(response.error) {
return console.log("Failed to delete dir: " + response.error.message);
}
console.log("Deleted directory: " + robots.data_path);
});
/*
Use `robots.delete(true, callback)`
to force deletion even if dir contains files
*/
To delete a directory, use the following endpoint:
DELETE https://api.algorithmia.com/v1/connector/:connector/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Query Parameters
| Parameters | Description |
|---|---|
| force | if true, enables recursive delete of a non-empty directory |
Response
| Attribute | Description |
|---|---|
| result.deleted | The number of files successfully deleted |
| error.deleted | The number of files successfully deleted if an error encountered during deletion |
Files
Files can be any type of data and are uniquely identified by a Data URI
Getting a file
Getting a file:
curl -O -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my/robots/T-800.png
# Downloaded to `T-800.png` in local working directory
# Download file to current directory with 'algo cp'
$ algo cp data://.my/robots/T-800.png .
Downloaded data://.my/robots/T-800.png (657kB)
Finished downloading 1 file(s)
# Echo file contents to STDOUT with 'algo cat'
$ algo cat data://.my/robots/T-800.txt
Cyberdyne Systems Series 800 Terminator
# Download file and get the file handle
t800File = client.file("data://.my/robots/T-800.png").getFile()
# Get file's contents as a string
t800Text = client.file("data://.my/robots/T-800.txt").getString()
# Get file's contents as JSON
t800Json = client.file("data://.my/robots/T-800.txt").getJson()
# Get file's contents as a byte array
t800Bytes = client.file("data://.my/robots/T-800.png").getBytes()
# Download file and get the file handle
t800File <- client$file("data://.my/robots/T-800.png")$getFile()
# Get file's contents as a string
t800Text <- client$file("data://.my/robots/T-800.txt")$getString()
# Get file's contents as JSON
t800Json <- client$file("data://.my/robots/T-800.txt")$getJson()
# Get file's contents as a byte array
t800Bytes <- client$file("data://.my/robots/T-800.png")$getBytes()
# Download file and get the file handle
t800File = client.file("data://.my/robots/T-800.png").get_file
# Get file's contents as a string
t800Text = client.file("data://.my/robots/T-800.txt").get
# Get file's contents as JSON
t800JsonString = client.file("data://.my/robots/T-800.txt").get
t800Json = JSON.parse(t800JsonString)
# Get file's contents as a byte array
t800Bytes = client.file("data://.my/robots/T-800.png").get
DataDirectory robots = client.dir("data://.my/robots");
// Download file and get the file handle
File t800File = robots.file("T-800.png").getFile();
// Get the file's contents as a string
String t800Text = robots.file("T-800.txt").getString();
// Get the file's contents as a byte array
byte[] t800Bytes = robots.file("T-800.png").getBytes();
val robots = client.dir("data://.my/robots")
// Download file and get the file handle
val t800File = robots.file("T-800.png").getFile()
// Get the file's contents as a string
val t800Text = robots.file("T-800.txt").getString()
// Get the file's contents as a byte array
val t800Bytes = robots.file("T-800.png").getBytes()
// Download and locally save file
let mut t800_png_reader = client.file("data://.my/robots/T-800.png").get().unwrap();
let mut t800_png = File::create("/path/to/save/t800.png").unwrap();
std::io::copy(&mut t800_png_reader, &mut t800_png);
// Get the file's contents as a string
let mut t800_text_reader = robots.file("data://.my/robots/T-800.txt").get().unwrap();
let mut t800_text = String::new();
t800_text_reader.read_to_string(&mut t800_text);
// Get the file's contents as a byte array
let mut t800_png_reader = robots.file("data://.my/robots/T-800.png").get().unwrap();
let mut t800_bytes = Vec::new();
t800_png_reader.read_to_end(&mut t800_bytes);
var robots = client.dir("data://.my/robots");
// Get the file's contents
robots.file("T-800.txt").get(function(err, data) {
// on success, data will be string or Buffer
console.log(response);
});
// Get a file and write it to a local file
robots.file("T-800.jpg").get(function(err, data) {
console.log("Read " + data.length + " bytes");
fs.writeFileSync("/path/to/save/T-800.jpg", data);
});
To retrieve a file through the Algorithmia Data API, use the following endpoint:
GET https://api.algorithmia.com/v1/connector/:connector/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Response
Upon 200 success, response body is the content of the file.
Response Headers:
X-Data-Type: file
Check if file exists
Checking if a file exists:
curl -I -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my/robots/HAL9000.png
->
HTTP/1.1 200 OK
Content-Length: 0
ETag: d41d8cd98f00b204e9800998ecf8427e
Strict-Transport-Security: max-age=0; includeSubDomains; preload
X-Data-Type: file
X-Frame-Options: DENY
Connection: keep-alive
if client.file("data://.my/robots/T-800.png").exists()
print("HAL 9000 exists")
if (client$file("data://.my/robots/T-800.png")$exists()){
print("HAL 9000 exists")
}
if client.file("data://.my/robots/T-800.png").exists?
puts "HAL 9000 exists"
if(client.file("data://.my/robots/HAL_9000.png").exists()){
System.out.println("HAL 9000 exists");
}
if(client.file("data://.my/robots/HAL_9000.png").exists()){
System.out.println("HAL 9000 exists")
}
if client.file("data://.my/robots/HAL_9000.png").exists().unwrap() {
println!("HAL 9000 exists");
}
var hal = client.file("data://.my/robots/HAL_9000.png");
hal.exists(function(exists) {
if(exists) {
console.log("HAL 9000 exists");
}
});
To check if a file exists without downloading it, use the following endpoint:
HEAD https://api.algorithmia.com/v1/connector/:connector/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Response
200 success indicates the file exists
Response Headers:
X-Data-Type: fileX-Error-Message: <Error message if error occurs>
Upload a file
Uploading a file:
# Write a text file
curl -X PUT -H 'Authorization: Simple YOUR_API_KEY' \
-d 'Leader of the Autobots' \
https://api.algorithmia.com/v1/connector/data/.my/robots/Optimus_Prime.txt
-> { "result": "data://.my/robots/Optimus_Prime.txt" }
# Upload local file
curl -X PUT -H 'Authorization: Simple YOUR_API_KEY' \
--data-binary @Optimus_Prime.png \
https://api.algorithmia.com/v1/connector/data/.my/robots/Optimus_Prime.png
-> { "result": "data://.my/robots/Optimus_Prime.png" }
# Upload files with 'algo cp'
$ algo cp Optimus_Prime.png data://.my/robots
Uploaded data://.my/robots/Optimus_Prime.png
Finished uploading 1 file(s)
# Upload local file
client.file("data://.my/robots/Optimus_Prime.png").putFile("/path/to/Optimus_Prime.png")
# Write a text file
client.file("data://.my/robots/Optimus_Prime.txt").put("Leader of the Autobots")
# Write a dict to a JSON file
client.file("data://.my/robots/Optimus_Prime.json").putJson({"faction": "Autobots"})
# Upload local file
client$file("data://.my/robots/Optimus_Prime.png")$putFile("/path/to/Optimus_Prime.png")
# Write a text file
client$file("data://.my/robots/Optimus_Prime.txt")$put("Leader of the Autobots")
# Write a list to a JSON file
client$file("data://.my/robots/Optimus_Prime.json")$putJson(list(faction="Autobots"))
robots = client.dir("data://.my/robots")
# Upload local file
robots.put_file("/path/to/Optimus_Prime.png")
# Write a text file
robots.file("Optimus_Prime.txt").put("Leader of the Autobots")
# Write a binary file
robots.file("Optimus_Prime.key").put([71, 101, 101, 107].pack('C*'))
DataDirectory robots = client.dir("data://.my/robots");
// Upload local file
robots.putFile(new File("/path/to/Optimus_Prime.png"));
// Write a text file
robots.file("Optimus_Prime.txt").put("Leader of the Autobots");
// Write a binary file
robots.file("Optimus_Prime.key").put(new byte[] { (byte)0xe0, 0x4f, (byte)0xd0, 0x20 });
val robots = client.dir("data://.my/robots")
// Upload local file
robots.putFile(new File("/path/to/Optimus_Prime.png"))
// Write a text file
robots.file("Optimus_Prime.txt").put("Leader of the Autobots")
// Write a binary file
robots.file("Optimus_Prime.key").put(new byte[] { (byte)0xe0, 0x4f, (byte)0xd0, 0x20 })
let robots = client.dir("data://.my/robots");
// Upload local file
robots.put_file("/path/to/Optimus_Prime.png");
// Write a text file
robots.child::<DataFile>("Optimus_Prime.txt").put("Leader of the Autobots");
// Write a binary file
robots.child::<DataFile>("Optimus_Prime.key").put(b"transform");
var robots = client.dir("data://.my/robots");
// Upload a file from a local path
robots.putFile("/path/to/Optimus_Prime.jpg", function(response) {
if(response.error) {
return console.log("Error: " + response.error.message);
}
console.log("Success");
});
// Write string or Buffer to a file
robots.file("Optimus_Prime.txt").put("Leader of the Autobots", function(response) {
/* check for error or success */
);
To upload a file through the Algorithmia Data API, use the following endpoint:
PUT https://api.algorithmia.com/v1/connector/data/:owner/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Input
Body of the request is the content of the file that will be created.
Response
| Attribute | Description |
|---|---|
| result | The full Data URI of resulting file |
Deleting a file
Deleting a file:
curl -X DELETE -H 'Authorization: Simple YOUR_API_KEY' \
https://api.algorithmia.com/v1/connector/data/.my/robots/C-3PO.txt
-> { "result": { "deleted": 1 }}
$ algo rm data://.my/robots/C-3PO.txt
Deleted file data://.my/robots/C-3PO.txt
c3po = client.file("data://.my/robots/C-3PO.txt")
c3po.delete()
c3po <- client$file("data://.my/robots/C-3PO.txt")
c3po$delete()
c3po = client.file("data://.my/robots/C-3PO.txt")
c3po.delete
DataFile c3po = client.file("data://.my/robots/C-3PO.txt")
c3po.delete();
val c3po = client.file("data://.my/robots/C-3PO.txt")
c3po.delete()
let c3po = client.file("data://.my/robots/C-3PO.txt");
c3po.delete();
var c3po = client.file("data://.my/robots/C-3PO.txt");
c3po.delete(function(response) {
if(response.error) {
return console.log("Failed to delete file: " + response.error.message);
}
console.log("Deleted file: " + c3po.data_path);
});
To delete a file through the Algorithmia Data API, use the following endpoint:
DELETE https://api.algorithmia.com/v1/connector/data/*path
:connectoris the data source:data,dropbox,s3, or a labeled variant (e.g.dropbox+mylabel).*pathis relative to the root of a given data source.
Response
| Attribute | Description |
|---|---|
| result.deleted | The number of files successfully deleted |
| error.deleted | The number of files successfully deleted if an error encountered during deletion |
API Versioning
Algorithmia API is versioned with the version specified on the URL route:
[ANY] api.algorithmia.com/:version/:route
The current supported API version is v1 (i.e. api.algorithmia.com/v1/:route)
Deprecated Versions
Algorithm API calls defined with unversioned routes are deprecated. Planned support for them ended 2015-12-31.
Unversioned routes are routes that use the following format:
[ANY] api.algorithmia.com/api/:route
[ANY] api.algorithmia.com/data/:route
Clients
Algorithmia clients are available as libraries for you to use inside your project. In addition to browsing the API specification to see language-specific usage for each API endpoint, client-specific guides are located in the Algorithmia Developer Center.
This table provides links to various resources for each client:
| Client | DevCenter Guide | GitHub Repo | Language Docs | Package |
|---|---|---|---|---|
| cURL | Guide | n/a | n/a | n/a |
| CLI | Guide | algorithmia-cli | n/a | Download |
| Java | Guide | algorithmia-java | Java Docs | Maven |
| JavaScript | Guide | n/a | n/a | Download |
| NodeJS | Guide | algorithmia-nodejs | n/a | NPM |
| Python | Guide | algorithmia-python | n/a | PyPi |
| R | Guide | algorithmia-r | R Docs | Cran |
| Ruby | Guide | algorithmia-ruby | n/a | RubyGems |
| Rust | Guide | algorithmia-rust | Cargo Docs | |
| Scala | Guide | algorithmia-java | Java Docs | Maven |
| AWS Lambda | Guide | algorithmia-nodejs | n/a | n/a |
| Swift | Guide | algorithmia-swift | Cocoa Pod Docs | |
| Go | Guide | algorithmia-go | Go Docs |
Algorithm Development
As an Algorithmia user, in addition to having access to hundreds of algorithms, you also have the ability to add your own algorithms. You can write a private algorithm for your own use, contribute an open source algorithm, or monetize an algorithm you authored. Our algorithms and platform are designed with composability in mind, so think of algorithms in the marketplace as building blocks.
We currently support algorithm development in:
Need Help?
We’re here to help you! If you are just getting started with Algorithmia, be sure to check out the guides and tutorials in the Algorithmia Developer Center.
This documentation is intended to help you integrate Algorithmia into your project or app, so if you haven’t found the answer to your question please reach out. We’d love to help you get up and running as soon as possible! We’re here to answer any question you might have, from pricing to troubleshooting to helping you publish an algorithm.
For any wrapper or library related issue, please open an issue on the dedicated GitHub repository.
Connect with us
- Follow us on Twitter!
- Check out the Algorithmia blog to stay up-to-date with new features and resources for using Algorithmia.
- Send us a quick message by clicking the ’?’ in the bottom right of your browser on the Algorithmia site.
- Shoot us an email at support@algorithmia.com.
Contribute to the docs
You can find the source code of this documentation as well as file issues on the repository.
Please contribute if you come across any errors or are having trouble understanding any of the information in these docs and guides. Your help improving the API documentation is much appreciated!