1. API Overview

The API is web-based (HTTP/HTTPS) and the primary input/output format for the API is JSON (mime-type: application/json). When necessary, endpoint-specific formats may be used such as application/octet-stream, application/xml, etc.

All text content is encoded as UTF-8. All API fields are written in American English, use lowercase characters, and follow snake_case format (multiple words are separated by underscores). When receiving input from a client, fields are treated as case-insensitive where possible.

The structure of the API is a standard REST mapping of URIs to resources and actions.

  • GET — used to retrieve information and should never mutate.
  • POST — used to create a new resource. It is also used to perform actions.
  • PUT — used to update an existing resource.
  • DELETE — used to delete or invalidate a resource.

HTTP status codes are used to indicate the success and failure of an API call, as well as the success field in the consistent response structure of all endpoints.

Most resources have a unique ID in the format of a UUID.

For authentication, the API uses secret api tokens, which is further detailed here.

The live endpoint for the API is https://api.innodata.com/v1.1. For example, you can find the status of the api at https://api.innodata.com/v1.1/status.

Consistent Response Structure

All API responses follow a consistent format. Unless the response content-type is exotic (i.e. not application/json), then the following structure is used:

  "success": boolean,    // indicates whether a call was successful
  "status_code": number, // the HTTP status code repeated in the response body for convenience
  "tracking": UUID,      // an ID that maps a specific API call to our debugging/logging
  "response": { ... }    // an endpoint-specific response

The use of a consistent format allows client writers to make clean assumptions about the structure of responses and easier to handle errors.

HTTP Status Codes and Errors

The following status codes are used to indicate failure/success.

  • 200 — the standard response for a success.
  • 201 — the response code for a successful creation of a new resource.
  • 400 — a general response code for an error in the client input (e.g. missing field, invalid format, etc).
  • 401 — a response indicating that the request failed, but may succeed if further authentication was successful.
  • 403 — a response indicating the request was not authorized to be performed (e.g. a user attempts to delete a document that exists but they do not have permission).
  • 404 — a response indicating that the resource at that URI does not exist (e.g. requesting a document by a non-existent ID).
  • 405 — a response indicating that the URI for a request was valid, but the request method was not (e.g. PUT /documents is not a valid endpoint).
  • 429 — a response indicating that API rate limits have been reached and that the user should "back off" until their rate limiting is expired.
  • 500 — an unexpected error code indicate the API did not intend to throw this error. Please retry the request and back off gradually.
  • 503 — a temporary error code indicating the API is under planned maintenance.

Errors follow a consistent format:

  "type": string,         // a unique error code
  "message": string,      // a human readable description
  "status_code": number,  // an HTTP status code corresponding to the error
  "fields": object | null, // a hint as to which fields are causing the error

For example, if a user fails to login, the example response would be:

POST https://api.innodata.com/v1.1/users/login
Content-type: application/json
  "auth_method": "password",
  "username": "Not.Real.User",
  "password": "password1234",

  "success": false,
  "status_code": 400,
  "tracking": "05732019-889d-4b43-8049-cf0dfe3c0d34",
  "response": [
      "type": "USER_NOT_FOUND",
      "message": "Username not found.",
      "status_code": 400,
      "fields": {
        "username": {
          "message": "Username not found."


API calls that return a list always support two consistent query parameters which allow clients to paginate the results.

  • limit — an integer indicating the number of items that should be returned in the list
  • offset — an integer indicating the starting position from which to start the list (0 would be the first item)

All list responses follow the same structure:

  "success": true,
  "status_code": 200,
  "tracking": "05732019-889d-4b43-8049-cf0dfe3c0d34",
  "response": {
    "limit": 25,
    "list": [...],
    "offset: 0,
    "total_count": 1000

API versioning and Environments

The API is versioned through the base URI. For example, version 1.1 of the API would be found at https://api.innodata.com/v1.1.

The current version of the API is version 1.1.

API keys come in two flavours. Live keys are prefixed with user-live- and should be used in production. Test keys, prefixed with user-test- can be used in development. Any data provided to the API with a test key will be removed on a regular basis. Furthermore, jobs which are created with a test key will not be curated by our human experts.