API

The VizSeek API provides a simple RESTful interface with lightweight JSON-formatted responses to use many of VizSeek's website features using OAuth. This document provides information to developers on how to integrate with the VizSeek API.



Intro


Use the VizSeek APIs to:

  • Upload files to be indexed to populate your searchable database.
  • Send search queries with a photo, 3D model, 2D drawing, or text as input.
  • Get back a set of visual search results.
If you don't have a VizSeek account yet, contact us to get started and set up a demo.

Delivery

VizSeek's APIs are REST APIs delivered over HTTP in JSON format. They are independent of your operating system, database system or development language. Libraries and language bindings to support REST and JSON are available in all major languages and platforms.


Access tokens

We use OAth 2.0 for authentication. That means an access token, either user or app, must be included in the header of every API call. The difference between a user access token and an app access token is that user access tokens are used when a login is required. For example, the API to upload a file (File PUT) requires a user access token, but the API to get the list of allowed files (ValidUploadFileTypes GET) only needs an app access token. The API Reference page specifies which APIs require a user access token. The rest require an app access token.

Note: A call made without an access token, or without the correct access token, will result in a 401 (Unauthorized) status.


Client Id

A client id is required to identify your application. Contact us to get an assigned client id.

Tutorials

  • C#
  • Java
  • Python 3

Download the complete example code here.
Contact us to get the local indexer installer.
Download the file used to start the local indexer process here.


Setup

All API calls should be inside the "using" statement
using (var client = new HttpClient())
{
    client.BaseAddress = new Uri("https://www.vizseek.com/api/");
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/json"));
}


Example of getting access tokens and using them to make a basic API call


private static string getAccessToken(HttpClient client, bool requiresUserToken)
{ 
    string accessToken = null;
    //check if the current access token has expired (this check should be done before any API call is made)
    DateTime tokenExpiration = requiresUserToken ? UserTokenExpiration : AppTokenExpiration; //UserTokenExpiration and AppTokenExpiration should be application-level variables (may have been set from a previous request).
    if (tokenExpiration <= DateTime.UtcNow)
    {
        //get an access token
        var formContent;
        if (requiresUserToken)
        {
            formContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("grant_type", "password"),
                new KeyValuePair<string, string>("username", "[user name]"),
                new KeyValuePair<string, string>("password", "[password]"), //use SHA1 hash (base64-encoded string) of your password
                new KeyValuePair<string, string>("client_id", "[your client id]")//contact us to get a client id
            });
            //Resources on SHA1 hashing:
            //https://stackoverflow.com/questions/40091771/sha-1-hashing-on-java-and-c-sharp
            //https://stackoverflow.com/questions/40740894/using-sha-1-in-net-core  
        }
        else
        {
            formContent = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("grant_type", "client_credentials"),
                new KeyValuePair<string, string>("client_id", "[your client id]")//contact us to get a client id
            });
        }
        HttpResponseMessage response = client.PostAsync("token", formContent).Result;
                    
        if (response.IsSuccessStatusCode)//request to get token was successful
        {
            //get access token and expiration from response
            var responseJson = response.Content.ReadAsStringAsync().Result;
            var jObject = JObject.Parse(responseJson);
            accessToken = jObject.GetValue("access_token").ToString();
            //note: "expires_in" is in seconds (typically the access token expiration is 30 minutes.
            DateTime expiration = DateTime.UtcNow.AddSeconds((double)Int32.Parse(jObject.GetValue("expires_in")));
            if (requiresUserToken)
            {
                UserTokenExpiration = expiration;
            }
            else
            {
                AppTokenExpiration = expiration;
            }
        }
    }
    else
    {
        accessToken = requiresUserToken ? UserAccessToken : AppAccessToken; //use stored application-level variable from a previous request
    }
    return accessToken;
}

//make an API call with a token
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + getAccessToken(client, false));
response = client.GetAsync("Version").Result;
if (response.IsSuccessStatusCode) //API call was successful
{        
    string version = response.Content.ReadAsAsync<string>().Result;
}

Example of getting your company ID (or "CompanyVizSpaceID")

Using the User GET API
//note: this API requires an app access token
//for the password, use SHA1 hash (base64-encoded string) of the password
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + getAccessToken(client, false));
HttpResponseMessage response = client.GetAsync("User?emailID=" + userEmail + "&password=" + userPassword).Result;

UserProfile user = response.Content.ReadAsAsync<UserProfile>().Result;
string myCompanyId = user.CompanyVizSpaceID;

Example of adding a file

Using the File PUT API
//note: this API requires a user access token

string fileContent = Convert.ToBase64String([byte array of the file]);
//attributes are URL encoded. For this example, attributes would be "color%3Dred%26size%3Dlarge"
string attributes = HttpUtility.UrlEncode("color=red&size=large");

//add to company file database (attributes are optional)
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + getAccessToken(client, true));
HttpResponseMessage response = client.PutAsJsonAsync("File?file=exampleFile.png&isSearchInput=false&attributes=" + attributes, JsonConvert.SerializeObject(fileContent)).Result;

//or add just for search. Note: isSearchInput's default value is true;
HttpResponseMessage response = client.PutAsJsonAsync("File?file=.png", JsonConvert.SerializeObject(fileContent)).Result;

string fileUID = response.Content.ReadAsAsync<string>().Result; //get the id of the added file

Example of searching with a file

Using the Search GET and Search PUT APIs
//note: the Search APIs require a user access token

//with Search GET - using the file we just added using File PUT
//filterStr is URL encoded
string filterStr = HttpUtility.UrlEncode("uid=[your company ID]&fileUID=" + fileUID + "&fileType=image");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + getAccessToken(client, true));
HttpResponseMessage response = client.GetAsync("Search?searchTypeStr=file&filterStr=" + filterStr).Result;

//or with Search PUT - using a new file
string[] byteArrays = new string[1];//multiple files could be used
byteArrays[0] = [byte array of the file];
string filterStr = HttpUtility.UrlEncode("uid=[your company id]&fileType=image");
HttpResponseMessage response = client.PutAsJsonAsync("Search?searchTypeStr=file&fileExtension=.png&filterStr=" + filterStr, JsonConvert.SerializeObject(byteArrays)).Result;

//using the search results. See the API Reference page for details about the SearchResultSummary object.
SearchResultSummary search = response.Content.ReadAsAsync<SearchResultSummary>().Result;


Download the complete example code here:  VizSeekAPI.java


Example of getting access tokens and using them to make a basic API call


private static String getAccessToken(boolean requiresUserToken) {
    String accessToken = null;
    //check if the current access token has expired (this check should be done before any API call is made)
    long tokenExpirationMillis = requiresUserToken ? UserTokenExpiration : AppTokenExpiration; //UserTokenExpiration and AppTokenExpiration should be application-level variables (may have been set from a previous request).
    if (tokenExpirationMillis <= System.currentTimeMillis()) {
        //note: username and password are only needed for getting a user access token, not an app access token
        //"grant_type=password" is used for getting a user access token. Use "grant_type=client_credentials" for getting an app access token
        String postString;
        if (requiresUserToken) {
            postString = String.format("grant_type=password&username=%s&password=%s&client_id=%s", [user name], [password], [your client id]);//use SHA1 hash (base64-encoded string) of the password
        } else {
            postString = String.format("grant_type=client_credentials&client_id=%s", [your client id]);
        }
        String RequestURL = "https://www.vizseek.com/api/token";
        StringBuilder sb = new StringBuilder();
        try {
            URL url = new URL(RequestURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(timeout);
            conn.setDoOutput(true);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Accept", "text/json");
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");

            byte[] outputInBytes = postString.getBytes("UTF-8");
            OutputStream os = conn.getOutputStream();
            os.write(outputInBytes);
            os.close();
            BufferedReader br;
            if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 299) {
                br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
            } else {
                br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
            }
            String output;
            while ((output = br.readLine()) != null)
                sb.append(output);
        } catch (MalformedURLException e) {
            e.printStackTrace();
            Log.i(TAG, "MalformedURLException: " + e);
        } catch (ProtocolException e) {
            e.printStackTrace();
            Log.i(TAG, "ProtocolException: " + e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.i(TAG, "IOException: " + e);
        }

        String response = sb.toString();
        //get access token from response
        try {
            JSONObject reader = new JSONObject(response);
            accessToken = reader.getString("access_token");
            //note: "expires_in" is in seconds (typically the access token expiration is 30 minutes.
            String expirationStr = reader.getString("expires_in");
            tokenExpirationMillis = Long.parseLong(expirationStr, 10) * 1000;
            if (requiresUserToken)
            {
                UserTokenExpiration = tokenExpirationMillis;
            }
            else
            {
                AppTokenExpiration = tokenExpirationMillis;
            }
            Log.i(TAG,access_token);
        }
        catch (JSONException e){
            e.printStackTrace();
        }
    } else {
        accessToken = requiresUserToken ? UserAccessToken : AppAccessToken; //use stored application-level variable from a previous request
    }

    return accessToken;
}

Example of adding a file

Using the File PUT API
//note: this API requires a user access token to be included in the header

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArrayImage = stream.toByteArray();

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArrayImage = stream.toByteArray();
//base64 encode the image
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);

String bodyStr = "\"\\\"" + encodedImage + "\\\"\"";

//add to company file database
String RequestURL = "File?file=exampleFile.png&isSearchInput=false&attributes=" + attributes;

//or add just for search. Note: isSearchInput's default value is true;
String RequestURL = "https://www.vizseek.com/api/File?file=.jpg";

StringBuilder sb = new StringBuilder();
try {
    URL url = new URL(RequestURL);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(timeout);
    conn.setRequestMethod("PUT");
    conn.setRequestProperty("Accept", "text/json");
    conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
    conn.addRequestProperty("Authorization", "Bearer " + getAccessToken(true));
    byte[] outputInBytes = bodyStr.getBytes("UTF-8");
    OutputStream os = conn.getOutputStream();
    os.write(outputInBytes);
    os.close();
    BufferedReader br;
    if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 299) {
        br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
    } else {
        br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
    }
    String output;
    while ((output = br.readLine()) != null)
        sb.append(output);
} catch (MalformedURLException e) {
    e.printStackTrace();
    Log.i(TAG, "MalformedURLException: " + e);
} catch (ProtocolException e) {
    e.printStackTrace();
    Log.i(TAG, "ProtocolException: " + e);
} catch (IOException e) {
    e.printStackTrace();
    Log.i(TAG, "IOException: " + e);
}
//returns the id of the added file
String response = sb.toString();
Log.i(TAG,response);

Example of searching with a file

Using the Search GET and Search PUT APIs
//note: the Search APIs require a user access token to be included in the header

//with Search GET - using the file we just added using File PUT
String filterStr = "uid="+ [your company id] + "&fileUID=" + fileUID + "&fileType=image";

try {
    //filterStr is URL encoded
    encodedfilterStr = URLEncoder.encode(filterStr, "utf-8");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

String URI = URI = "searchTypeStr=" + [your company type (file or prod)] + "&filterstr=" + encodedfilterStr;
String RequestURL = "https://www.vizseek.com/api/Search";

try {
    URL url = new URL(RequestURL + "?" + URI);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(timeout);
    conn.setRequestMethod("PUT");
    conn.setRequestProperty("Accept", "text/json");
    conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
    conn.addRequestProperty("Authorization", "Bearer " + getAccessToken(true));
    BufferedReader br;
    if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 299) {
        br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
    } else {
        br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
    }
    String output;
    while ((output = br.readLine()) != null)
        sb.append(output);
} catch (MalformedURLException e) {
    e.printStackTrace();
    Log.i(TAG, "MalformedURLException: " + e);
} catch (ProtocolException e) {
    e.printStackTrace();
    Log.i(TAG, "ProtocolException: " + e);
} catch (IOException e) {
    e.printStackTrace();
    Log.i(TAG, "IOException: " + e);
}

String response = sb.toString();
Log.i(TAG,response);


//or with Search PUT - using a new file
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArrayImage = stream.toByteArray();

//base64 encode the image
String encodedImage = Base64.encodeToString(byteArrayImage, Base64.DEFAULT);

ArrayList<String> inputImageArrayList= new ArrayList<String>;
inputImageArrayList.add(encodedImage)

String bodyStrl;
//multiple files could be used
if (inputImageArrayList.size() > 1) {
    for (int i = 1; i < inputImageArrayList.size(); i++) {
        str += "\\\",\\\"" + inputImageArrayList.get(i);
    }
    bodyStr = "\"[\\\"" + str + "\\\"]\"";
} else {
    Log.i("VizSeek", "single image!");
    bodyStr = "\"[\\\"" + inputImageArrayList.get(0) + "\\\"]\"";
}

String filterStr = "uid="+ [your company id] + "&fileExtension=.jpg&isGZipCompressed=false&fileType=image";

String encodedfilterStr = "";
try {
    encodedfilterStr = URLEncoder.encode(filterStr, "utf-8");
} catch (UnsupportedEncodingException e) {
    e.printStackTrace();
}

String URI = URI = "searchTypeStr=" + [your company type (file or prod)] + "&filterstr=" + encodedfilterStr + "&fileExtension=.jpg&isGZipCompressed=false";
String RequestURL = "https://www.vizseek.com/api/Search";

StringBuilder sb = new StringBuilder();
try {
    URL url = new URL(RequestURL + "?" + URI);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(timeout);
    conn.setRequestMethod("PUT");
    conn.setRequestProperty("Accept", "text/json");
    conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");
    conn.addRequestProperty("Authorization", "Bearer " + getAccessToken(true));
    byte[] outputInBytes = bodyStr.getBytes("UTF-8");
    OutputStream os = conn.getOutputStream();
    os.write(outputInBytes);
    os.close();
    BufferedReader br;
    if (200 <= conn.getResponseCode() && conn.getResponseCode() <= 299) {
        br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
    } else {
        br = new BufferedReader(new InputStreamReader((conn.getErrorStream())));
    }
    String output;
    while ((output = br.readLine()) != null)
        sb.append(output);
} catch (MalformedURLException e) {
    e.printStackTrace();
    Log.i(TAG, "MalformedURLException: " + e);
} catch (ProtocolException e) {
    e.printStackTrace();
    Log.i(TAG, "ProtocolException: " + e);
} catch (IOException e) {
    e.printStackTrace();
    Log.i(TAG, "IOException: " + e);
}

String response = sb.toString();
Log.i(TAG,response);


Download the complete example code here.


See the full list of API methods here.