API version 2.0 (the documentation for the previous version is here). The other way to integrate your API with our API Management solution is to use the 3scale REST API for authenticating calls and reporting usage.

Documentation

This document describes the protocol used for your API to communicate with 3scale backend server for authorizing and reporting transactions between your infrastructure and your API users.

Definitions

service
any web service implementing an API
provider
an organization, company or individual providing a service
application
a consumer endpoint of a web service (website, embeddable widget, desktop program, mobile application, HTTP enabled microwave oven, ...)
transaction
Single unit of interaction between an application and a service. In case of HTTP-base web services, this is usually one request-response exchange.
resource
Anything that is spent during a transaction and can be measured. This can be for example CPU time spent during the processing, or storage space used for storing some data, and so on.
metric
A way to measure a resource. For example: number of API hits, amount of disk space in megabytes, CPU time in milliseconds, ...
provider key
Unique textual identifier of a provider.
application id
Public unique textual identifier of an application.
application key
Secret key for authenticating transactions.

Operations

The API exposes a simple REST-based interface that provides these operations: authorize, and report.

Authorize

Read-only operation to authorize an application. It is used to check if a particular application exists, is active and is within usage limits of the service. It can be optionally used to authenticate a call using an application key.
GET /transactions/authorize.xml?app_id={app_id}&provider_key={provider_key}[&app_key={app_key}]
Parameters
provider_key
Provider key. Required.
service_id
Service id. Required only if as a provider you have multiple services allowed and enabled.
app_id
Application id. Required.
app_key
Application key. Required only if it is defined for the application.
referrer
Referrer IP Address or Domain. Required if referrer filtering is enabled. If special value "*" (start) is passed, the referrer check is bypassed.
usage
Predicted usage. Optional
Predicted usage
It's possible to pass a "predicted usage" to the authorize call. This can serve two purposes:
  1. To make sure an API call won't go over the limits before the call is made, if the usage of the call is known in advance. In this case, the estimated usage can be passed to the authorize call, and it will respond whether the actual API call is still within limit. In other words, without the usage parameter, authorize only checks the usage that has already been reported. If the usage parameter is passes in, it will check whether the already reported usage + the passed in predicted usage is still within limit.
  2. To limit the authorization only to a subset of metrics. If usage is passed in, only the metrics listed in it will be checked against the limits. For example: There are two metrics defined: searches and updates. updates are already over limit, but searches are not. In this case, the user should still be allowed to do a search call, but not an update one. To authorize this, pass usage[searches]=1 to the authorize call.

NOTE: Even if the predicted usage is passed in, authorize is still a read-only operation. You have to make the report call to report the usage.

NOTE: usage is an associative array of the form {metric : value}. Please reefer to the "Encoding complex data structures in URLs" appendix for more info.

NOTE: usage can be either a positive integer (e.g. 1, 50) or a positive integer prefixed with the character '#' (e.g. #1, #50). In the first case, the value of the usage will be incremented, whereas in the second case will be set to the numerical value. Thus, usage[hits]=1 will increment the hits counter by +1, whereas usage[hits]=#1 will set the hits counters to 1.

Setting the value of a counter with the prefix '#' to wherever the usage is present. However, this is something that needs to be handled with care because it can raise concurrency issues. For instance, in the case of two (or more) concurrent requests: usage[hits]=#1, usage[hits]=#10 it is not possible to determine the final value of hits, it can be either 1 or 10 depending on which was the last request processed by 3scale's backend. We cannot ensure order preserving or reconciliation. In the case of usage[hits]=1 and usage[hits]=10, the final value of hits would have been incremented by 11.

Another potential issue with setting the value of a counter with the prefix '#' is that in the case applying to methods (metrics that are children of metrics) the parent will also be take the value of the child. For instance, let's assume that views and save are methods of the metric hits, thus views and save are children of hits. In this case, if we do usage[save]=1 and usage[views]=3, the value of views will be increased by 3, the value of save will be increased by 1 and the value of hits will be implicitly increased by 4 (3+1). On the other hand, doing a usage[save]=#1 and usage[views]=#3 will set the value of views to 3, the value of save will be set to 1, but the value of hits will be set to either 3 or 1 depending which method was processed last.

Successful Response
Has status code 200 OK (if authorization is granted), 409 (if it's not granted) and a body containing authorization result, failure reason (if authorization failed), the plan type and list of usage report entries for every current metric limit. Example of successful authorize response
<status>
  <authorized>true</authorized>
  <plan>Pro</plan>

  <usage_reports>
    <usage_report metric="hits" period="month">
      <period_start>2010-08-01 00:00:00 +00:00</period_start>
      <period_end>2010-09-01 00:00:00 +00:00</period_end>
      <current_value>17344</current_value>
      <max_value>20000</max_value>
    </usage_report>

    <usage_report metric="hits" period="day">
      <period_start>2010-08-04 00:00:00 +00:00</period_start>
      <period_end>2010-08-05 00:00:00 +00:00</period_end>
      <current_value>732</current_value>
      <max_value>1000</max_value>
    </usage_report>
  </usage_reports/>
</status>
Example of failed authorize response (exceeded limits)
<status>
  <authorized>false</authorized>
  <reason>Usage limits are exceeded</reason>
  <plan>Pro</plan>

  <usage_reports>
    <usage_report metric="hits" period="month">
      <period_start>2010-08-01 00:00:00 +00:00</period_start>
      <period_end>2010-09-01 00:00:00 +00:00</period_end>
      <current_value>17344</current_value>
      <max_value>20000</max_value>
    </usage_report>

    <usage_report metric="hits" period="day" exceeded="true">
      <period_start>2010-08-04 00:00:00 +00:00</period_start>
      <period_end>2010-08-05 00:00:00 +00:00</period_end>
      <current_value>1042</current_value>
      <max_value>1000</max_value>
    </usage_report>
  </usage_reports/>
</status>
Explanation of the elements
status
Root element of the response.
authorized
Contains text "true" if the authorization was successful, or "false" if it failed.
reason
Human readable textual description of failure reason. This element appears only if authorize is false.
plan
Name of the plan the user is signed up to.
usage_reports
Contains list of usage_report elements - one per each usage limit defined for the plan the user is signed up to.
usage_report
Contains information about usage status. Contains these elements: period_start, period_end, current_value and max_value. Has attributes metric with the name of the metric the limit applies to, period, which is the period of the limit (year, month, week, day, hour, minute) and optionally exceeded which is set to "true" if the limit is exceeded in the current period.
period_start
Start of the limit period. It's in the form YYYY-MM-DD HH:MM:SS +ZZ:ZZ. +ZZ:ZZ (or -ZZ:ZZ) is a time offset (in hours and minutes) from UTC.
period_end
End of the limit period. Same format as period_start
current_value
Value of the corresponding metric accumulated so far in the current period.
max_value
Maximum value allowed by the usage limit.
Errors
In case of error, the response body contains an XML-formatted object with a single element error. This element has one attribute code containing a unique string identifier of the error. The content of this element is a human-readable English description of the error. These are all possible error identifiers and their meanings:
provider_key_invalid
Provider key is not valid
application_not_found
Application with the given id does not exist.
This is an example of an error response:
<?xml version="1.0" encoding="utf-8" ?>
<error code="application_not_found">Application with id="12345678" was not found</error>
Example Request
GET /transactions/authorize.xml?app_id=709deaac&provider_key=pkey&app_key=app_key HTTP/1.1

Host: su1.3scale.net
Example Request with referrer
GET /transactions/authorize.xml?app_id=709deaac&provider_key=pkey&app_key=app_key&referrer=example.org HTTP/1.1

Host: su1.3scale.net
Example Request with usage
GET /transactions/authorize.xml?app_id=709deaac&provider_key=pkey&app_key=app_key&usage[hits]=1&usage[transfer]=1024 HTTP/1.1

Host: su1.3scale.net
Example Request with usage and service_id
GET /transactions/authorize.xml?service_id=7812315&app_id=709deaac&provider_key=pkey&app_key=app_key&usage[hits]=1&usage[transfer]=1024 HTTP/1.1

Host: su1.3scale.net

OAuth Authorize

It's a modified version of the authorize call that returns some extra data that is needed to power OAuth APIs. It's only available for users with OAuth enabled APIs.
GET /transactions/oauth_authorize.xml?app_id={app_id}&provider_key={provider_key}[&app_key={app_key}]
Parameters
provider_key
Provider key. Required.
service_id
Service id. Required only if as a provider you have multiple services allowed and enabled.
app_id
Application id. Required.
app_key
Application key. Optionl. Will be validated if sent.
referrer
Referrer IP Address or Domain. Required if referrer filtering is enabled. If special value "*" (start) is passed, the referrer check is bypassed.
usage
Predicted usage. Optional
redirect_url
Redirect URL for OAuth. Optional. Will be validated if sent.
Successful Response
Has status code 200 OK (if authorization is granted), 409 (if it's not granted) and a body containing authorization result, failure reason (if authorization failed), the plan type and list of usage report entries for every current metric limit. Example of successful authorize response
<status>
  <authorized>true</authorized>
  <plan>Pro</plan>

  <application>
    <id>57c53c8a</id>
    <key>433dbee8b34524326a2b4a3c126ec5c3</key>
    <redirect_url>http://www.example.com/redirect_url</redirect_url>
  </application>

  <usage_reports>
    <usage_report metric="hits" period="month">
      <period_start>2010-08-01 00:00:00 +00:00</period_start>
      <period_end>2010-09-01 00:00:00 +00:00</period_end>
      <current_value>17344</current_value>
      <max_value>20000</max_value>
    </usage_report>

    <usage_report metric="hits" period="day">
      <period_start>2010-08-04 00:00:00 +00:00</period_start>
      <period_end>2010-08-05 00:00:00 +00:00</period_end>
      <current_value>732</current_value>
      <max_value>1000</max_value>
    </usage_report>
  </usage_reports/>
</status>
Example of failed authorize response (exceeded limits)
<status>
  <authorized>false</authorized>
  <reason>Usage limits are exceeded</reason>
  <plan>Pro</plan>

  <application>
    <id>57c53c8a</id>
    <key>433dbee8b34524326a2b4a3c126ec5c3</key>
    <redirect_url>http://www.example.com/redirect_url</redirect_url>
  </application>

  <usage_reports>
    <usage_report metric="hits" period="month">
      <period_start>2010-08-01 00:00:00 +00:00</period_start>
      <period_end>2010-09-01 00:00:00 +00:00</period_end>
      <current_value>17344</current_value>
      <max_value>20000</max_value>
    </usage_report>

    <usage_report metric="hits" period="day" exceeded="true">
      <period_start>2010-08-04 00:00:00 +00:00</period_start>
      <period_end>2010-08-05 00:00:00 +00:00</period_end>
      <current_value>1042</current_value>
      <max_value>1000</max_value>
    </usage_report>
  </usage_reports/>
</status>
Explanation of the elements
status
Root element of the response.
authorized
Contains text "true" if the authorization was successful, or "false" if it failed.
reason
Human readable textual description of failure reason. This element appears only if authorize is false.
plan
Name of the plan the user is signed up to.
application
Parent element that holds the application details.
id
ID of the application. Matches the sent app_id.
key
Key of the application. You should use this as your OAuth v1.0a secret or OAuth v2.0 key.
redirect_url
Rdirect URL configured by the author of the application. If it's a web application you might be interested in making sure you'll only redirect users to this URL.
usage_reports
Contains list of usage_report elements - one per each usage limit defined for the plan the user is signed up to.
usage_report
Contains information about usage status. Contains these elements: period_start, period_end, current_value and max_value. Has attributes metric with the name of the metric the limit applies to, period, which is the period of the limit (year, month, week, day, hour, minute) and optionally exceeded which is set to "true" if the limit is exceeded in the current period.
period_start
Start of the limit period. It's in the form YYYY-MM-DD HH:MM:SS +ZZ:ZZ. +ZZ:ZZ (or -ZZ:ZZ) is a time offset (in hours and minutes) from UTC.
period_end
End of the limit period. Same format as period_start
current_value
Value of the corresponding metric accumulated so far in the current period.
max_value
Maximum value allowed by the usage limit.
Errors
In case of error, the response body contains an XML-formatted object with a single element error. This element has one attribute code containing a unique string identifier of the error. The content of this element is a human-readable English description of the error. These are all possible error identifiers and their meanings:
provider_key_invalid
Provider key is not valid
application_not_found
Application with the given id does not exist.
This is an example of an error response:
<?xml version="1.0" encoding="utf-8" ?>
<error code="application_not_found">Application with id="12345678" was not found</error>
Example Request
GET /transactions/oauth_authorize.xml?app_id=709deaac&provider_key=pkey&app_key=app_key HTTP/1.1

Host: su1.3scale.net

Authrep

"One-shot" operation to authorize an application and report traffic. The only difference between this call and the regular authorize call is that metric usage will be reported if the authorization is successful. For additional examples of authrep calls you can see the examples or authorize calls, all parameters in authorized are also valid in the authrep case.
GET /transactions/authrep.xml?app_id={app_id}&provider_key={provider_key}[&app_key={app_key}]&usage[hits]=1
Parameters
provider_key
Provider key. Required.
service_id
Service id. Required only if as a provider you have multiple services allowed and enabled.
app_id
Application id. Required.
app_key
Application key. Required only if it is defined for the application.
referrer
Referrer IP Address or Domain. Required if referrer filtering is enabled. If special value "*" (start) is passed, the referrer check is bypassed.
usage
Metric usage. If the authorization succeeds and the application is still within the limits with this usage, it's aggregated to the application statistics and usage limits.
log
Log requests. Optional, available only to certain 3scale's plans. If allowed and enabled it let's you log requests/responses/response_codes of your API, such logs will be accessible on your admin portal as a providers as well as on the buyer portal for the users of your API.
Usage
The usage parameters should be passed along in order to report traffic.
  1. This will make sure an API call won't go over the limits. It will check whether the already reported usage + the passed in usage is still within limit.
  2. If the authorization is successful the usage will then be "reported" and aggregated for statistics and usage limits purposes. There is no need to make a second call to report the traffic since this is already taken care of.
NOTE: usage is an associative array of the form {metric : value}. Please refer to the "Encoding complex data structures in URLs" appendix for more info.
Log
The log parameters should be passed along in order to keep a log of your API requests.
  1. This parameter is optional and it is only allowed to certain 3scale's plans. If as providers you have log requests allowed and enabled you can send the body of the API requests, responses and status code to 3scale so that you can keep a log of the latest activity of your API. Please refer to the "Log Request" appendix for more info.
  2. In addition, log is an associative array of the form {request : value, response : value, code : value}. Please refer to the "Encoding complex data structures in URLs" appendix for more info.
  3. The request in log is required whereas the rest are optional and can be left blank. Additionally, the values for log they have to be url-encoded.
Example Request with usage
GET /transactions/authrep.xml?app_id=709deaac&provider_key=pkey&app_key=app_key&usage[hits]=1&usage[storage]=500 HTTP/1.1

Host: su1.3scale.net
Example Request with logs
GET /transactions/authrep.xml?app_id=709deaac&provider_key=pkey&app_key=app_key&usage[hits]=1&usage[storage]=500&log[request]=%2Fmethod1.xml%3Fkey%3DXXX%26id%3DYYYY%26usage%5Bbla%5D%3D1&log[response]=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3Cerror+code%3D%22key_invalid%22%3Ekey+%22XXX%22+is+invalid%3C%2F& log[code]=200& HTTP/1.1

Host: su1.3scale.net
Successful Response
Has status code 200 OK (if authorization is granted - and therefore reported), 409 (if it's not granted) and a body containing authorization result, failure reason (if authorization failed), the plan type and list of usage report entries for every current metric limit.

Report

This operation is used to report 3scale system about transactions. Any number of transactions can be reported in one request. POST /transactions.xml
Parameters
transactions
List of parameters for each transaction in the batch. More details are explained below. Required.
provider_key
Provider key. Required.
service_id
Service id. Required only if as a provider you have multiple services allowed and enabled.
The structure of the transactions parameter
The transactions should contain numerically indexed list of records, one for each transaction. Each record can contain these parameters:
app_id
Application ID. Required.
usage
Usage data of the transaction. This should be associative array (a hash) of the form: {metric => value, ...}, where metric is name of the metric that measures the particular resource (for example "storage" or "hits") and value is any amount of the corresponding resource spend in the transaction. Required.
timestamp
If given, should be date and time when the transaction occurred. It can be specified in two ways: First, in UTC (Greenwich time), second, in any other time zone. In the first case, the timestamp has to be in this format: YYYY-MM-DD HH:MM:SS for example 2009-01-01 17:45:02. In the second case, the format has to be YYYY-MM-DD HH:MM:SS +HH:MM or YYYY-MM-DD HH:MM:SS -HH:MM, where the +HH:MM (or -HH:MM) part specifies the time offset from UTC in hours and minutes. For example, for timestamp in PST (Pacific Standard Time), it should look like this: 2009-01-01 22:15:31 -08:00. Optional. If not specified, the time when the transaction was received is used.
log
This parameter is optional and it is only allowed to certain 3scale's plans. If as providers you have log requests allowed and enabled you can send the body of the API requests, responses and status code to 3scale so that you can keep a log of the latest activity of your API. Please refer to the "Log Request" appendix for more info. In addition, log is an associative array of the form {request : value, response : value, code : value}. Please refer to the "Encoding complex data structures in URLs" appendix for more info. The request in log is required whereas the rest are optional and can be left blank. Additionally, the values for log they have to be url-encoded.
These parameters have to be encoded in HTTP POST request using the application/x-www-form-urlencoded media type. Please reefer to the "Encoding complex data structures in URLs" appendix for more info.
Successful Response
Has status code 202 Accepted and no response body
Errors
Processing transactions, especially if there is lot of them, can be time consuming task. To achieve low response times, most of the processing is actually done offline. Fot this reason, there are two ways the errors are reported:
Errors detected during request processing
Only one type of error can occur during request processing - invalid provider key. In case the provider key is not valid, the response has status code 403 Forbidden and the body contains XML document with description of the error. Example:
<?xml version="1.0" encoding="utf-8" ?>
<error code="provider_key_invalid">Provider key "abcd1234" is invalid</error>
Errors detected during offline processing
If an error occurs during offline processing, it's description is stored and can be examined by visiting the provider admin area on www.3scale.net. Errors that can occur in the offline processing are: Note that transactions from a single batch are reported only if all of them are valid. If there is an error in processing of at least one of them, none is reported. Note that a batch can only report transactions to the same service, service_id is at the same level that provider_key. Multiple report calls will have to be issued to report transactions to different services.
Example Request
POST /transactions.xml HTTP/1.1
Host: su1.3scale.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 428

transactions[0][app_id]=app_id&
transactions[0][usage][hits]=1&
transactions[0][usage][transfer]=4500&
transactions[0][timestamp]=2009-01-01%2014%3A23%3A08&
transactions[1][app_id]=app_id&
transactions[1][usage][hits]=1&
transactions[1][usage][transfer]=2840&
transactions[1][timestamp]=2009-01-01%2018%3A11%3A59&
provider_key=pkey
Example Request with Service id
A batch can only report transactions to the same service, service_id has to be
POST /transactions.xml HTTP/1.1
Host: su1.3scale.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 428

transactions[0][app_id]=app_id&
transactions[0][usage][hits]=1&
transactions[0][usage][transfer]=4500&
transactions[0][timestamp]=2009-01-01%2014%3A23%3A08&
transactions[1][app_id]=app_id&
transactions[1][usage][hits]=1&
transactions[1][usage][transfer]=2840&
transactions[1][timestamp]=2009-01-01%2018%3A11%3A59&
provider_key=pkey&
service_id=78910
Example Request with log
The transactions contain the requests/response/code of the API in log. These will be logged and can be retrieved on the admin and buyer portal.
POST /transactions.xml HTTP/1.1
Host: su1.3scale.net
Content-Type: application/x-www-form-urlencoded

transactions[0][app_id]=app_id&
transactions[0][usage][hits]=1&
transactions[0][usage][transfer]=4500&
transactions[0][timestamp]=2009-01-01%2014%3A23%3A08&
transactions[0][log][request]=%2Fmethod1.xml%3Fkey%3DXXX%26id%3DYYYY%26usage%5Bbla%5D%3D1 &
transactions[0][log][response]=%3C%3Fxml+version%3D%221.0%22+encoding%3D%22UTF-8%22%3F%3E%3Cerror+code%3D%22key_invalid%22%3Ekey+%22XXX%22+is+invalid%3C%2F&
transactions[0][log][code]=200&
09-01-01%2018%3A11%3A59&
provider_key=pkey&
service_id=78910

Appendix: Log requests detail

To enable the API log requests the provider has to send the information on what needs to be reported on their calls to the Service Management API. Every log entry contains
request
Required. The API request to the provider sent by the user
response
Optional. the API response generated by the provider to be sent to the user
code
Optional. Additional string to denote supplementary information, could be the http_status_code or other semantically relevant string like success or failure
All the strings need to be url encoded, for instance, blank spaces need to be replaced by "+" or by "%20", etc. Additionally there is a cap to the length of the log data:
  • MAX_LEN_REQUEST = 1024 bytes
  • MAX_LEN_RESPONSE = 4096 bytes
  • MAX_LEN_CODE = 32 bytes
  • Appendix (II): Encoding complex data structures in URLs

    The usual way to encode a complex data structure (array, associative array, nested structures) is to "flatten" it. For example, having this structure:
    {
      "0": {
        "app_id": "app_id",
        "usage": {"hits": 1, "transfer": 4500},
        "timestamp": "2009-01-01 14:23:08"},
    
      "1": {
        "app_id": "app_id",
        "usage": {"hits": 1, "transfer": 2840},
        "timestamp": "2009-01-01 18:11:59"}}
    It has to be encoded like this:
    transactions[0][app_id]=app_id&
    transactions[0][usage][hits]=1&
    transactions[0][usage][transfer]=4500&
    transactions[0][timestamp]=2009-01-01%2014%3A23%3A08&
    transactions[1][app_id]=app_id&
    transactions[1][usage][hits]=1&
    transactions[1][usage][transfer]=2840&
    transactions[1][timestamp]=2009-01-01%2018%3A11%3A59
    (note that spaces are encoded as %20 and colons as %3A according to URL encoding rules)