Supertext Home
Chief of the System Blog

The Supertext REST API

February 22nd, 2012 by

What?

In the early days, the internet solely consisted of simple static webpages. With the Dot-Com boom (or bubble), the webpages changed into complex and dynamic applications. But they were all like islands. There was no connection whatsoever between them. But now, companies like Facebook and Twitter loosened up and enable other people to build applications, allowing to connect to them and add their own functionality.

Until now, Supertext has – besides some specific integrations – been an island too. But that’s over now. We have an open and public API allowing other applications to directly integrate with Supertext.

 

Why?

Who wants to integrate with Supertext you wonder? And why? Actually, lots of people. It started 4 years ago with Akero, a now defunct CMS system. Akero users were able to directly order translations and text editing from inside their CMS and got the final text delivered back into it. Clearly, this wasn’t enough to make Akero a success, but the need to order directly from 3rd party systems remained evident until today.

 

How?

Now it gets a bit technical. The Supertext API is built as a REST API that understands JSON or XML. Almost all modern open APIs are built alike. This means that they’re accessible with normal HTTP calls and they enable you to send and receive human readable JSON or XML messages.

 

Who?

Authentication is done via normal Basic HTTP Authentication. Most other APIs just use a token or your username and password. We decided to work with a username in combination with a custom token. You can get this token from your Supertext Account Settings page. If you don’t have a Supertext account, you can establish one on the sign up page.

 

Where?

Please send an e-mail to remyATsupertextDOTch and I will send you the URL for the sandbox and the live system.

 

Which?

Currently we support the functionality listed below, basically you can get quotes and make orders.

You can add the below parameter to most calls, to specify in what language you get the results back:

communicationlang={communicationlang}

Adding it is optional. Otherwise the response defaults to English.  We currently support CHF and EUR. For a quote you can choose between the two currencies, but if you create an order, whatever is set in your account will be used.

 

For the configuration

/translation/languagemapping/{language}

GET – No authentication necessary.

Helps you map a language in your system to one we support.

E.g. your CMS is setup for ‘de’ (German). We don’t actually translate into German, we translate into German for Switzerland, for Germany or for Austria. So this method returns you a list of possible matches. For {language} = ‘de’ the result would look like this:

{
  "Languages":
  [
    {
      "Iso":"de-CH",
      "Name":"German (CH)"
    },
    {
      "Iso":"de-DE",
      "Name":"German (DE)"
    },
    {
      "Iso":"de-AT",
      "Name":"German (AT)"
    }
  ],
  "Supported":false
}

 

To get a quote

/translation/quote

POST – authentication optional

Getting a quote over the API works in pretty much the same way as if you were using our normal website to order a translation (give it a try). Send us the text and in return, you see a list of possible delivery deadlines and prices per service levels  (translation/adaptation). You can send us the content structured in groups and items, which is helpful if you have CMS that is built that way. E.g. a group could be a page, items are title, content, metatags and so on. The following is a possible JSON for this call:

{
  "ContentType":"text\/html",
  "Currency":"chf",
  "Groups":
  [
    {
      "GroupId":"Group1",
      "Items":
      [
        {
          "Content":"This is the content of group 1",
        },
        {
          "Content":"This is more content  of group 1",
        }
      ]
    },
    {
      "GroupId":"Group2",
      "Items":
      [
        {
          "Content":"This is the content  of group 2",
          "Id":"1"
        },
        {
          "Comment":"Some info about this message",
          "Content":"This is a twitter message, that can't be longer than 140 chars.",
          "Context":"Twitter",
          "Id":"2"
          "MaxLength":"140"
        }
      ]
    }
  ],
  "Files":
  [
    {
      "ID": 17015,
      "Comment":"The main story with 585 words"
     }
   ],
  "SourceLang":"de-CH",
  "TargetLanguages":["de-ch", "ru"],
}

 

For the quote you don’t need to specify fields like Id, Context, etc. Only the Content field is important and only the Content filed will be counted.

If you don’t have the content yet, or if you already know the word count you can alternatively specify the WordCount field. It takes precedence over the content in the Groups collection. If you use your own word count the final price might be a bit different, since we will eventually count the content our self and use that count to calculate the final price.

{
  "ContentType":"text\/html",
  "Currency":"chf",
  "SourceLang":"de-CH",
  "TargetLanguages":["de-ch", "ru"],
  "WordCount": 235
}

 

And this could be what you get in return:

 

{
  "Currency":"CHF",
  "WordCount": 123,
  "Options":
  [
    {
      "DeliveryOptions":
      [
        {
          "DeliveryDate":"2012-02-22T09:25:46.0000000Z",
          "DeliveryId":1,
          "Name":"6h",
          "Price":124
        },
        {
          "DeliveryDate":"2012-02-22T15:25:46.0000000Z0",
          "DeliveryId":2,
          "Name":"24h",
          "Price":110
        },
        {
          "DeliveryDate":"2012-02-23T15:25:46.0000000Z",
          "DeliveryId":3,
          "Name":"48h",
          "Price":96
        },
        {
          "DeliveryDate":"2012-02-24T15:25:46.0000000Z",
          "DeliveryId":4,
          "Name":"3 Days",
          "Price":82
        },
        {
          "DeliveryDate":"2012-02-28T15:25:46.0000000Z",
          "DeliveryId":5,
          "Name":"1 Week",
          "Price":69
        }
      ],
      "Description":"For an exact reproduction of the original text, the translated text is checked by a proofreader.",
      "Name":"Translation",
      "OrderTypeId":6,
      "ShortDescription":"4-eye principle."
    },
    {
      "DeliveryOptions":
      [
        {
          "DeliveryDate":"2012-02-22T15:25:46.0000000Z",
          "DeliveryId":2,
          "Name":"24h",
          "Price":254
        },
        {
          "DeliveryDate":"2012-02-23T15:25:46.0000000Z",
          "DeliveryId":3,
          "Name":"48h",
          "Price":222
        },
        {
          "DeliveryDate":"2012-02-24T15:25:46.0000000Z",
          "DeliveryId":4,
          "Name":"3 Days",
          "Price":190
        },
        {
          "DeliveryDate":"2012-02-28T15:25:46.0000000Z",
          "DeliveryId":5,
          "Name":"1 Week",
          "Price":159
        }
      ],
      "Description":"For the translation to sound as good as the original, the translated text is stylistically post-edited.",
      "Name":"Adaptation",
      "OrderTypeId":7,
      "ShortDescription":"6-eye principle."
    }
  ]
}

 

In the above example, you didn’t specify an OrderTypeId or a ServiceTypeId. In this case the Translation service (4) will be used as a default and you get a selection of different translation options. You can only specify a ServiceTypeId OR an OrderTypeId, but not both.

Possible ServiceTypeId and OrderTypeId values:

ServiceTypeId Service
1 Text Tuning Services
OrderTypeId Order type
1 Total Revision
2 Feintuning
2 Creation
OrderTypeId Order type
3 Creation Solo
4 Creation Trio (Only on request)
3 Proofreading Service (launch 2014)
OrderTypeId Order type
5 Proofreading
10 Proofreading Duo
4 Translation Services
OrderTypeId Order type
6 Translation
8 Specialist Translation
9 Transcreation

If you already know which order type you want, you can specify it and then you will only get the price/delivery options for that type.

Make an order

/translation/order

POST – authentication necessary

When making an order, we need more details than we need for a quote. At first, we need to know which quote you’ve chosen. So you have to add the OrderTypeId and the DeliveryId.

Very important is the CallbackUrl. After the translation job is finished, we will call this URL with a similar JSON order object and write back the translated content into your system.

We strongly advise you to use the following fields:

OrderName: Some short description about this order. E.g. “Spring sale”

ReferenceData: Anything you need to identify this order later (besides the GroupId and the Id for the Content field). And optionally, you could add some security token so that not everybody with access to the callback URL can update your system.

Referrer: Name of your website or system. E.g. Supertext US Website

 

{
  "CallbackUrl":"http://localhost:65346/API/ApiCallbackExample.aspx",
  "ContentType":"text\/html",
  "Currency":"chf",
  "DeliveryId":1,
  "OrderName":"Some title",  
  "AdditionalInformation":"Please make sure you always translate this like that.",
  "OrderTypeId":6,
  "ReferenceData":"NodeId:4ee69461-1c8d-4fbe-9d77-7d05e46bc4a8",
  "Referrer":"Supertext Magazin",
  "SourceLang":"de-CH",
  "TargetLanguages":["de-ch", "ru"],
  "Files":
  [
    {
      "ID": 17015,
      "Comment":"The main story with 585 words"
     }
   ],
  "Groups":
  [
    {
      "Context":"Some Node",
      "GroupId":"Group1",
      "Items":
      [
        {
          "Comment":null,
          "Content":"This is the content of group 1",
          "Context":null,
          "Id":"1"
        },
        {
          "Comment":null,
          "Content":"This is new content of group 1",
          "Context":null,
          "Id":"2"
        }
      ]
    },
    {
      "Context":"Some other Node",
      "GroupId":"Group2",
      "Items":
      [
        {
          "Comment":null,
          "Content":"This is the content of group 2",
          "Context":null,
          "Id":"1"
        },
        {
          "Comment":"Some info about this message",
          "Content":"This is a twitter message, that can't be longer than 140 chars.",
          "Context":"Twitter",
          "Id":"2"
          "MaxLength":"140"
        }
      ]
    }
  ]
}

 

Comment, Context, MaxLength are optional. The Id is important so that you will know where to write this item back into your system. We don’t guarantee the sequence. MaxLength is helpful for things like Twitter Messages or fixed length fields, so that we don’t translate this item with too many characters.

You get back another order object with the order Id, a price, order and delivery date. All the other data is just for your reference.

 

{
  "Id":12023,
  "OrderDate":"2012-02-09T13:43:46.0000000Z",
  "Deadline":"2012-02-09T13:43:46.0000000Z",
  "Price":199,
  "Currency":"chf",
  "DeliveryId":1,
  "OrderTitle":"Some title",
  "OrderTypeId":6,
  "ReferenceData":"NodeId:4ee69461-1c8d-4fbe-9d77-7d05e46bc4a8",
  "SourceLang":"de-CH",
  "TargetLang":"en-US",
  "Status":"New"
}

 

Status

/translation/order/{id}

GET – authentication necessary

In order to track the status of an order, just use the Id you got after you submitted the order. You will get an Order object like the one above as a return.

 

Callback
In order to get your translation back from us, you need to provide us with a callback URL.
When you create the order, you have to use the field CallbackUrl. This URL needs to accept a JSON of the type Order (as shown above). That Order object will contain your translation in the Groups and Item fields with the same Id’s, so you can map them back to your own datastructure.
We recommend that you use the ReferenceData field as some type of authentication. For example you could use a combination of an internal Id and the MD5 hash of this Id. We will return the ReferenceData field in our callback. You can then just check if the Hash matches to make sure nobody else is writing into your system.

 

Dates

All dates are in UTC and in the ISO_8601 format:

2012-05-03T12:09:46.0000000Z

If you are using .NET just use Convert.ToDateTime(), this will automatically convert from the UTC time to your local time.

2 Comments to “The Supertext REST API”

Leave a Reply

  • Topics
  • Archive
  • Subscribe
  • Facebook
  • Twitter